Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Wilkins2015-09-17 22:30:02 -0400
committerGreg Wilkins2015-09-17 22:30:02 -0400
commit99f4ed7352504072753e14615fe0e3471a00824b (patch)
tree03d60adef1959bbfee2254675a22044fee0a6a14 /jetty-servlet
parentd39677a6359e9e768b35cff7957227ea14b8bb7a (diff)
downloadorg.eclipse.jetty.project-99f4ed7352504072753e14615fe0e3471a00824b.tar.gz
org.eclipse.jetty.project-99f4ed7352504072753e14615fe0e3471a00824b.tar.xz
org.eclipse.jetty.project-99f4ed7352504072753e14615fe0e3471a00824b.zip
477737 Improve handling of etags with dynamic and static gzip
Diffstat (limited to 'jetty-servlet')
-rw-r--r--jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java28
-rw-r--r--jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java42
2 files changed, 55 insertions, 15 deletions
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java
index 8041eb0687..be9e81423f 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java
@@ -18,6 +18,9 @@
package org.eclipse.jetty.servlet;
+import static org.eclipse.jetty.http.GzipHttpContent.ETAG_GZIP_QUOTE;
+import static org.eclipse.jetty.http.GzipHttpContent.removeGzipFromETag;
+
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@@ -40,6 +43,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.DateParser;
+import org.eclipse.jetty.http.GzipHttpContent;
import org.eclipse.jetty.http.HttpContent;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
@@ -693,6 +697,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
if (request instanceof Request)
{
+ // Find multiple fields by iteration as an optimization
HttpFields fields = ((Request)request).getHttpFields();
for (int i=fields.size();i-->0;)
{
@@ -730,16 +735,17 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
{
if (_etags)
{
+ String etag=content.getETagValue();
if (ifm!=null)
{
boolean match=false;
- if (content.getETagValue()!=null)
+ if (etag!=null)
{
QuotedStringTokenizer quoted = new QuotedStringTokenizer(ifm,", ",false,true);
while (!match && quoted.hasMoreTokens())
{
String tag = quoted.nextToken();
- if (content.getETagValue().equals(tag))
+ if (etag.equals(tag) || tag.endsWith(ETAG_GZIP_QUOTE) && etag.equals(removeGzipFromETag(tag)))
match=true;
}
}
@@ -751,33 +757,25 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
}
}
- if (ifnm!=null && content.getETagValue()!=null)
+ if (ifnm!=null && etag!=null)
{
- // Look for Gzip'd version of etag
- if (content.getETagValue().equals(request.getAttribute("o.e.j.s.Gzip.ETag")))
+ // Handle special case of exact match OR gzip exact match
+ if (etag.equals(ifnm) || ifnm.endsWith(ETAG_GZIP_QUOTE) && ifnm.indexOf(',')<0 && etag.equals(removeGzipFromETag(etag)))
{
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
response.setHeader(HttpHeader.ETAG.asString(),ifnm);
return false;
}
- // Handle special case of exact match.
- if (content.getETagValue().equals(ifnm))
- {
- response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
- response.setHeader(HttpHeader.ETAG.asString(),content.getETagValue());
- return false;
- }
-
// Handle list of tags
QuotedStringTokenizer quoted = new QuotedStringTokenizer(ifnm,", ",false,true);
while (quoted.hasMoreTokens())
{
String tag = quoted.nextToken();
- if (content.getETagValue().equals(tag))
+ if (etag.equals(tag) || tag.endsWith(ETAG_GZIP_QUOTE) && etag.equals(removeGzipFromETag(tag)))
{
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
- response.setHeader(HttpHeader.ETAG.asString(),content.getETagValue());
+ response.setHeader(HttpHeader.ETAG.asString(),tag);
return false;
}
}
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java
index 8a5c3f2ca0..174c85f87d 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java
@@ -731,6 +731,32 @@ public class DefaultServletTest
assertResponseNotContains("Content-Encoding: gzip",response);
assertResponseNotContains("ETag: "+etag_gzip,response);
assertResponseContains("ETag: ",response);
+
+ response = connector.getResponses("GET /context/data0.txt.gz HTTP/1.0\r\nHost:localhost:8080\r\nAccept-Encoding:gzip\r\nIf-None-Match: W/\"wobble\"\r\n\r\n");
+ assertResponseContains("Content-Length: 9", response);
+ assertResponseContains("fake gzip",response);
+ assertResponseContains("Content-Type: application/gzip",response);
+ assertResponseNotContains("Vary: Accept-Encoding",response);
+ assertResponseNotContains("Content-Encoding: gzip",response);
+ assertResponseNotContains("ETag: "+etag_gzip,response);
+ assertResponseContains("ETag: ",response);
+
+ response = connector.getResponses("GET /context/data0.txt HTTP/1.0\r\nHost:localhost:8080\r\nAccept-Encoding:gzip\r\nIf-None-Match: "+etag_gzip+"\r\n\r\n");
+ assertResponseContains("304 Not Modified", response);
+ assertResponseContains("ETag: "+etag_gzip,response);
+
+ response = connector.getResponses("GET /context/data0.txt HTTP/1.0\r\nHost:localhost:8080\r\nAccept-Encoding:gzip\r\nIf-None-Match: "+etag+"\r\n\r\n");
+ assertResponseContains("304 Not Modified", response);
+ assertResponseContains("ETag: "+etag,response);
+
+ response = connector.getResponses("GET /context/data0.txt HTTP/1.0\r\nHost:localhost:8080\r\nAccept-Encoding:gzip\r\nIf-None-Match: W/\"foobar\","+etag_gzip+"\r\n\r\n");
+ assertResponseContains("304 Not Modified", response);
+ assertResponseContains("ETag: "+etag_gzip,response);
+
+ response = connector.getResponses("GET /context/data0.txt HTTP/1.0\r\nHost:localhost:8080\r\nAccept-Encoding:gzip\r\nIf-None-Match: W/\"foobar\","+etag+"\r\n\r\n");
+ assertResponseContains("304 Not Modified", response);
+ assertResponseContains("ETag: "+etag,response);
+
}
@Test
@@ -784,6 +810,22 @@ public class DefaultServletTest
assertResponseNotContains("Content-Encoding: gzip",response);
assertResponseNotContains("ETag: "+etag_gzip,response);
assertResponseContains("ETag: ",response);
+
+ response = connector.getResponses("GET /context/data0.txt HTTP/1.0\r\nHost:localhost:8080\r\nAccept-Encoding:gzip\r\nIf-None-Match: "+etag_gzip+"\r\n\r\n");
+ assertResponseContains("304 Not Modified", response);
+ assertResponseContains("ETag: "+etag_gzip,response);
+
+ response = connector.getResponses("GET /context/data0.txt HTTP/1.0\r\nHost:localhost:8080\r\nAccept-Encoding:gzip\r\nIf-None-Match: "+etag+"\r\n\r\n");
+ assertResponseContains("304 Not Modified", response);
+ assertResponseContains("ETag: "+etag,response);
+
+ response = connector.getResponses("GET /context/data0.txt HTTP/1.0\r\nHost:localhost:8080\r\nAccept-Encoding:gzip\r\nIf-None-Match: W/\"foobar\","+etag_gzip+"\r\n\r\n");
+ assertResponseContains("304 Not Modified", response);
+ assertResponseContains("ETag: "+etag_gzip,response);
+
+ response = connector.getResponses("GET /context/data0.txt HTTP/1.0\r\nHost:localhost:8080\r\nAccept-Encoding:gzip\r\nIf-None-Match: W/\"foobar\","+etag+"\r\n\r\n");
+ assertResponseContains("304 Not Modified", response);
+ assertResponseContains("ETag: "+etag,response);
}
@Test

Back to the top