Issue #623 Add gzip suffix to etags in 304 response
This commit is contained in:
parent
f86d72696a
commit
f4c13e5f54
|
@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||
|
||||
import org.eclipse.jetty.http.GzipHttpContent;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
|
@ -443,6 +444,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
|
|||
int i=etag.indexOf(GzipHttpContent.ETAG_GZIP_QUOTE);
|
||||
if (i>0)
|
||||
{
|
||||
baseRequest.setAttribute("o.e.j.s.h.gzip.GzipHandler.etag",etag);
|
||||
while (i>=0)
|
||||
{
|
||||
etag=etag.substring(0,i)+etag.substring(i+GzipHttpContent.ETAG_GZIP.length());
|
||||
|
|
|
@ -157,6 +157,19 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor
|
|||
{
|
||||
LOG.debug("{} exclude by status {}",this,sc);
|
||||
noCompression();
|
||||
|
||||
if (sc==304)
|
||||
{
|
||||
String request_etags = (String)_channel.getRequest().getAttribute("o.e.j.s.h.gzip.GzipHandler.etag");
|
||||
String response_etag = response.getHttpFields().get(HttpHeader.ETAG);
|
||||
if (request_etags!=null && response_etag!=null)
|
||||
{
|
||||
String response_etag_gzip=etagGzip(response_etag);
|
||||
if (request_etags.contains(response_etag_gzip))
|
||||
response.getHttpFields().put(HttpHeader.ETAG,response_etag_gzip);
|
||||
}
|
||||
}
|
||||
|
||||
_interceptor.write(content, complete, callback);
|
||||
return;
|
||||
}
|
||||
|
@ -216,11 +229,7 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor
|
|||
response.setContentLength(-1);
|
||||
String etag=fields.get(HttpHeader.ETAG);
|
||||
if (etag!=null)
|
||||
{
|
||||
int end = etag.length()-1;
|
||||
etag=(etag.charAt(end)=='"')?etag.substring(0,end)+GzipHttpContent.ETAG_GZIP+'"':etag+GzipHttpContent.ETAG_GZIP;
|
||||
fields.put(HttpHeader.ETAG,etag);
|
||||
}
|
||||
fields.put(HttpHeader.ETAG,etagGzip(etag));
|
||||
|
||||
LOG.debug("{} compressing {}",this,_deflater);
|
||||
_state.set(GZState.COMPRESSING);
|
||||
|
@ -231,6 +240,12 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor
|
|||
callback.failed(new WritePendingException());
|
||||
}
|
||||
|
||||
private String etagGzip(String etag)
|
||||
{
|
||||
int end = etag.length()-1;
|
||||
return (etag.charAt(end)=='"')?etag.substring(0,end)+GzipHttpContent.ETAG_GZIP+'"':etag+GzipHttpContent.ETAG_GZIP;
|
||||
}
|
||||
|
||||
public void noCompression()
|
||||
{
|
||||
while (true)
|
||||
|
|
|
@ -19,10 +19,14 @@
|
|||
package org.eclipse.jetty.servlet;
|
||||
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalToIgnoringCase;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
@ -42,6 +46,7 @@ import org.eclipse.jetty.server.LocalConnector;
|
|||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -62,6 +67,8 @@ public class GzipHandlerTest
|
|||
"Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse "+
|
||||
"et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque.";
|
||||
|
||||
private static String __contentETag = String.format("W/\"%x\"",__content.hashCode());
|
||||
private static String __contentETagGzip = String.format("W/\"%x--gzip\"",__content.hashCode());
|
||||
private static String __icontent = "BEFORE"+__content+"AFTER";
|
||||
|
||||
private Server _server;
|
||||
|
@ -75,6 +82,7 @@ public class GzipHandlerTest
|
|||
_server.addConnector(_connector);
|
||||
|
||||
GzipHandler gzipHandler = new GzipHandler();
|
||||
gzipHandler.setExcludedAgentPatterns();
|
||||
|
||||
ServletContextHandler context = new ServletContextHandler(gzipHandler,"/ctx");
|
||||
ServletHandler servlets = context.getServletHandler();
|
||||
|
@ -93,8 +101,15 @@ public class GzipHandlerTest
|
|||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
PrintWriter writer = response.getWriter();
|
||||
writer.write(__content);
|
||||
response.setHeader("ETag",__contentETag);
|
||||
String ifnm = req.getHeader("If-None-Match");
|
||||
if (ifnm!=null && ifnm.equals(__contentETag))
|
||||
response.sendError(304);
|
||||
else
|
||||
{
|
||||
PrintWriter writer = response.getWriter();
|
||||
writer.write(__content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,6 +140,33 @@ public class GzipHandlerTest
|
|||
_server.join();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotGzipHandler() throws Exception
|
||||
{
|
||||
// generated and parsed test
|
||||
HttpTester.Request request = HttpTester.newRequest();
|
||||
HttpTester.Response response;
|
||||
|
||||
request.setMethod("GET");
|
||||
request.setURI("/ctx/content");
|
||||
request.setVersion("HTTP/1.0");
|
||||
request.setHeader("Host","tester");
|
||||
|
||||
response = HttpTester.parseResponse(_connector.getResponses(request.generate()));
|
||||
|
||||
assertThat(response.getStatus(),is(200));
|
||||
assertThat(response.get("Content-Encoding"),not(equalToIgnoringCase("gzip")));
|
||||
assertThat(response.get("ETag"),is(__contentETag));
|
||||
assertThat(response.get("Vary"),is("Accept-Encoding"));
|
||||
|
||||
InputStream testIn = new ByteArrayInputStream(response.getContentBytes());
|
||||
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
|
||||
IO.copy(testIn,testOut);
|
||||
|
||||
assertEquals(__content, testOut.toString("UTF8"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGzipHandler() throws Exception
|
||||
{
|
||||
|
@ -133,22 +175,65 @@ public class GzipHandlerTest
|
|||
HttpTester.Response response;
|
||||
|
||||
request.setMethod("GET");
|
||||
request.setURI("/ctx/content");
|
||||
request.setVersion("HTTP/1.0");
|
||||
request.setHeader("Host","tester");
|
||||
request.setHeader("accept-encoding","gzip");
|
||||
request.setURI("/ctx/content");
|
||||
|
||||
response = HttpTester.parseResponse(_connector.getResponses(request.generate()));
|
||||
|
||||
assertTrue(response.get("Content-Encoding").equalsIgnoreCase("gzip"));
|
||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||
assertThat(response.getStatus(),is(200));
|
||||
assertThat(response.get("Content-Encoding"),Matchers.equalToIgnoringCase("gzip"));
|
||||
assertThat(response.get("ETag"),is(__contentETagGzip));
|
||||
assertThat(response.get("Vary"),is("Accept-Encoding"));
|
||||
|
||||
InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
|
||||
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
|
||||
IO.copy(testIn,testOut);
|
||||
|
||||
assertEquals(__content, testOut.toString("UTF8"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testETagNotGzipHandler() throws Exception
|
||||
{
|
||||
// generated and parsed test
|
||||
HttpTester.Request request = HttpTester.newRequest();
|
||||
HttpTester.Response response;
|
||||
|
||||
request.setMethod("GET");
|
||||
request.setURI("/ctx/content");
|
||||
request.setVersion("HTTP/1.0");
|
||||
request.setHeader("Host","tester");
|
||||
request.setHeader("If-None-Match",__contentETag);
|
||||
request.setHeader("accept-encoding","gzip");
|
||||
|
||||
response = HttpTester.parseResponse(_connector.getResponses(request.generate()));
|
||||
|
||||
assertThat(response.getStatus(),is(304));
|
||||
assertThat(response.get("Content-Encoding"),not(Matchers.equalToIgnoringCase("gzip")));
|
||||
assertThat(response.get("ETag"),is(__contentETag));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testETagGzipHandler() throws Exception
|
||||
{
|
||||
// generated and parsed test
|
||||
HttpTester.Request request = HttpTester.newRequest();
|
||||
HttpTester.Response response;
|
||||
|
||||
request.setMethod("GET");
|
||||
request.setURI("/ctx/content");
|
||||
request.setVersion("HTTP/1.0");
|
||||
request.setHeader("Host","tester");
|
||||
request.setHeader("If-None-Match",__contentETagGzip);
|
||||
request.setHeader("accept-encoding","gzip");
|
||||
|
||||
response = HttpTester.parseResponse(_connector.getResponses(request.generate()));
|
||||
|
||||
assertThat(response.getStatus(),is(304));
|
||||
assertThat(response.get("Content-Encoding"),not(Matchers.equalToIgnoringCase("gzip")));
|
||||
assertThat(response.get("ETag"),is(__contentETagGzip));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -166,8 +251,10 @@ public class GzipHandlerTest
|
|||
|
||||
response = HttpTester.parseResponse(_connector.getResponses(request.generate()));
|
||||
|
||||
assertTrue(response.get("Content-Encoding").equalsIgnoreCase("gzip"));
|
||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||
assertThat(response.getStatus(),is(200));
|
||||
assertThat(response.get("Content-Encoding"),Matchers.equalToIgnoringCase("gzip"));
|
||||
assertThat(response.get("ETag"),is(__contentETagGzip));
|
||||
assertThat(response.get("Vary"),is("Accept-Encoding"));
|
||||
|
||||
InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
|
||||
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
|
||||
|
@ -190,9 +277,11 @@ public class GzipHandlerTest
|
|||
request.setURI("/ctx/include");
|
||||
|
||||
response = HttpTester.parseResponse(_connector.getResponses(request.generate()));
|
||||
|
||||
assertTrue(response.get("Content-Encoding").equalsIgnoreCase("gzip"));
|
||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||
|
||||
assertThat(response.getStatus(),is(200));
|
||||
assertThat(response.get("Content-Encoding"),Matchers.equalToIgnoringCase("gzip"));
|
||||
assertThat(response.get("ETag"),nullValue());
|
||||
assertThat(response.get("Vary"),is("Accept-Encoding"));
|
||||
|
||||
InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
|
||||
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
|
||||
|
|
Loading…
Reference in New Issue