tapestry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jkuhn...@apache.org
Subject svn commit: r481641 - in /tapestry/tapestry4/trunk/tapestry-framework/src: java/org/apache/tapestry/asset/AssetService.java test/org/apache/tapestry/valid/TestUrlValidator.java
Date Sat, 02 Dec 2006 22:11:17 GMT
Author: jkuhnert
Date: Sat Dec  2 14:11:16 2006
New Revision: 481641

URL: http://svn.apache.org/viewvc?view=rev&rev=481641
Log:
Vastly improved AssetService cache header response handling. Page load times should go way
way down with 
cahcing enabled, and when caching is disabled it will actually accurately report the last
modified 
time of each resource in question. (instead of generically using some other time, like system
startup/ etc..)

Hard to describe how much faster things become. 

Modified:
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/asset/AssetService.java
    tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/valid/TestUrlValidator.java

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/asset/AssetService.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/asset/AssetService.java?view=diff&rev=481641&r1=481640&r2=481641
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/asset/AssetService.java
(original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/asset/AssetService.java
Sat Dec  2 14:11:16 2006
@@ -14,8 +14,6 @@
 
 package org.apache.tapestry.asset;
 
-import java.io.BufferedInputStream;
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -32,10 +30,10 @@
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
 import org.apache.hivemind.ClassResolver;
 import org.apache.hivemind.util.Defense;
-import org.apache.hivemind.util.IOUtils;
 import org.apache.tapestry.IRequestCycle;
 import org.apache.tapestry.Tapestry;
 import org.apache.tapestry.engine.IEngineService;
@@ -101,8 +99,6 @@
         _mimeTypes.put("html", "text/html");
     }
 
-    private static final int BUFFER_SIZE = 10240;
-
     private static final DateFormat CACHED_FORMAT = new SimpleDateFormat("EEE, d MMM yyyy
HH:mm:ss Z", Locale.ENGLISH);
     
     /** Represents a month of time in seconds. */
@@ -229,6 +225,8 @@
         String md5Digest = cycle.getParameter(DIGEST);
         boolean checkDigest = !_unprotectedMatcher.containsResource(path);
         
+        URLConnection resourceConnection = null;
+        
         try
         {
             if (checkDigest
@@ -254,21 +252,22 @@
                 _response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                 _log.warn(AssetMessages.noSuchResource(path));
                 return;
-                // throw new ApplicationRuntimeException(AssetMessages.noSuchResource(path));
             }
             
+            resourceConnection = resourceURL.openConnection();
+            
             // check caching for unprotected resources
             
-            if (!checkDigest && cachedResource(resourceURL))
+            if (!checkDigest && cachedResource(resourceConnection))
                 return;
             
-            URLConnection resourceConnection = resourceURL.openConnection();
-            
             writeAssetContent(cycle, path, resourceConnection);
         }
         catch (Throwable ex)
         {
             _exceptionReporter.reportRequestException(AssetMessages.exceptionReportTitle(path),
ex);
+        } finally {
+            resourceConnection = null;
         }
 
     }
@@ -331,13 +330,8 @@
      * @since 4.1
      */
     
-    boolean cachedResource(URL resourceURL)
+    boolean cachedResource(URLConnection resourceURL)
     {
-        File resource = new File(resourceURL.getFile());
-        
-        if (!resource.exists()) 
-            return false;
-        
         // even if it doesn't exist in header the value will be -1, 
         // which means we need to write out the contents of the resource
         
@@ -349,7 +343,7 @@
                 modify = CACHED_FORMAT.parse(header).getTime();
         } catch (ParseException e) { e.printStackTrace(); }
         
-        if (resource.lastModified() > modify
+        if (resourceURL.getLastModified() > modify
                 || (_lastResetTime > modify))
             return false;
         
@@ -376,48 +370,47 @@
 
             if (contentLength > 0)
                 _response.setContentLength(contentLength);
-
-            _response.setDateHeader("Last-Modified", _startupTime);
-            _response.setDateHeader("Expires", _expireTime);
+            
+            long lastModified = _startupTime;
+            if (_lastResetTime > 0)
+                lastModified = _lastResetTime;
+            else
+                lastModified = resourceConnection.getLastModified();
+            
+            _response.setDateHeader("Last-Modified", lastModified);
+            
+            // write out expiration/cache info
+            
+            if (_lastResetTime <= 0) {
+                
+                _response.setDateHeader("Expires", _expireTime);
+                _response.setHeader("Cache-Control", "max-age=" + (MONTH_SECONDS * 3));
+                _response.setHeader("ETag", String.valueOf(resourcePath.hashCode()));
+            }
             
             // Set the content type. If the servlet container doesn't
             // provide it, try and guess it by the extension.
-
+            
             if (contentType == null || contentType.length() == 0)
                 contentType = getMimeType(resourcePath);
             
-            // force image caching when detected, esp helps with ie related things
+            input = resourceConnection.getInputStream();
+            
+            byte[] data = IOUtils.toByteArray(input);
+            
+            // force image(or other) caching when detected, esp helps with ie related things
             // see http://mir.aculo.us/2005/08/28/internet-explorer-and-ajax-image-caching-woes
             
-            if (contentType != null && "image".indexOf(contentType) > -1) {
-                
-                _response.setHeader("Cache-Control", "max-age=" + MONTH_SECONDS);
-                
-                _response.setHeader("ETag", String.valueOf(resourcePath.hashCode()));
-            }
+            _response.setContentLength(data.length);
             
             OutputStream output = _response.getOutputStream(new ContentType(contentType));
-
-            input = new BufferedInputStream(resourceConnection.getInputStream());
-
-            byte[] buffer = new byte[BUFFER_SIZE];
-
-            while (true)
-            {
-                int bytesRead = input.read(buffer);
-
-                if (bytesRead < 0)
-                    break;
-
-                output.write(buffer, 0, bytesRead);
-            }
-
-            input.close();
-            input = null;
+            
+            output.write(data);
         }
         finally
         {
-            IOUtils.close(input);
+            IOUtils.closeQuietly(input);
+            input = null;
         }
     }
 

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/valid/TestUrlValidator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/valid/TestUrlValidator.java?view=diff&rev=481641&r1=481640&r2=481641
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/valid/TestUrlValidator.java
(original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/valid/TestUrlValidator.java
Sat Dec  2 14:11:16 2006
@@ -30,7 +30,7 @@
  * @author Jimmy Dyson
  * @since 3.0
  */
-@Test
+@Test(sequential=true)
 public class TestUrlValidator extends BaseValidatorTestCase
 {
     private UrlValidator v = new UrlValidator();



Mime
View raw message