Merge remote-tracking branch 'origin/jetty-9.4.x'
This commit is contained in:
commit
3fafd6ee8f
|
@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.eclipse.jetty.http.CompressedContentFormat;
|
import org.eclipse.jetty.http.CompressedContentFormat;
|
||||||
import org.eclipse.jetty.http.HttpField;
|
import org.eclipse.jetty.http.HttpField;
|
||||||
|
import org.eclipse.jetty.http.HttpFields;
|
||||||
import org.eclipse.jetty.http.HttpHeader;
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
import org.eclipse.jetty.http.HttpMethod;
|
import org.eclipse.jetty.http.HttpMethod;
|
||||||
import org.eclipse.jetty.http.HttpVersion;
|
import org.eclipse.jetty.http.HttpVersion;
|
||||||
|
@ -478,6 +479,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
|
||||||
int i=etag.indexOf(CompressedContentFormat.GZIP._etagQuote);
|
int i=etag.indexOf(CompressedContentFormat.GZIP._etagQuote);
|
||||||
if (i>0)
|
if (i>0)
|
||||||
{
|
{
|
||||||
|
baseRequest.setAttribute("o.e.j.s.h.gzip.GzipHandler.etag",etag);
|
||||||
while (i>=0)
|
while (i>=0)
|
||||||
{
|
{
|
||||||
etag=etag.substring(0,i)+etag.substring(i+CompressedContentFormat.GZIP._etag.length());
|
etag=etag.substring(0,i)+etag.substring(i+CompressedContentFormat.GZIP._etag.length());
|
||||||
|
|
|
@ -158,6 +158,19 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor
|
||||||
{
|
{
|
||||||
LOG.debug("{} exclude by status {}",this,sc);
|
LOG.debug("{} exclude by status {}",this,sc);
|
||||||
noCompression();
|
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);
|
_interceptor.write(content, complete, callback);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -217,11 +230,7 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor
|
||||||
response.setContentLength(-1);
|
response.setContentLength(-1);
|
||||||
String etag=fields.get(HttpHeader.ETAG);
|
String etag=fields.get(HttpHeader.ETAG);
|
||||||
if (etag!=null)
|
if (etag!=null)
|
||||||
{
|
fields.put(HttpHeader.ETAG,etagGzip(etag));
|
||||||
int end = etag.length()-1;
|
|
||||||
etag=(etag.charAt(end)=='"')?etag.substring(0,end)+ GZIP._etag+'"':etag+GZIP._etag;
|
|
||||||
fields.put(HttpHeader.ETAG,etag);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG.debug("{} compressing {}",this,_deflater);
|
LOG.debug("{} compressing {}",this,_deflater);
|
||||||
_state.set(GZState.COMPRESSING);
|
_state.set(GZState.COMPRESSING);
|
||||||
|
@ -232,6 +241,12 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor
|
||||||
callback.failed(new WritePendingException());
|
callback.failed(new WritePendingException());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String etagGzip(String etag)
|
||||||
|
{
|
||||||
|
int end = etag.length()-1;
|
||||||
|
return (etag.charAt(end)=='"')?etag.substring(0,end)+ GZIP._etag+'"':etag+GZIP._etag;
|
||||||
|
}
|
||||||
|
|
||||||
public void noCompression()
|
public void noCompression()
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
|
|
|
@ -19,10 +19,14 @@
|
||||||
package org.eclipse.jetty.servlet;
|
package org.eclipse.jetty.servlet;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.contains;
|
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.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.assertEquals;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
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.Server;
|
||||||
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
|
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
|
||||||
import org.eclipse.jetty.util.IO;
|
import org.eclipse.jetty.util.IO;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -62,6 +67,8 @@ public class GzipHandlerTest
|
||||||
"Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse "+
|
"Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse "+
|
||||||
"et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque.";
|
"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 static String __icontent = "BEFORE"+__content+"AFTER";
|
||||||
|
|
||||||
private Server _server;
|
private Server _server;
|
||||||
|
@ -75,6 +82,7 @@ public class GzipHandlerTest
|
||||||
_server.addConnector(_connector);
|
_server.addConnector(_connector);
|
||||||
|
|
||||||
GzipHandler gzipHandler = new GzipHandler();
|
GzipHandler gzipHandler = new GzipHandler();
|
||||||
|
gzipHandler.setExcludedAgentPatterns();
|
||||||
|
|
||||||
ServletContextHandler context = new ServletContextHandler(gzipHandler,"/ctx");
|
ServletContextHandler context = new ServletContextHandler(gzipHandler,"/ctx");
|
||||||
ServletHandler servlets = context.getServletHandler();
|
ServletHandler servlets = context.getServletHandler();
|
||||||
|
@ -93,8 +101,15 @@ public class GzipHandlerTest
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException
|
protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException
|
||||||
{
|
{
|
||||||
PrintWriter writer = response.getWriter();
|
response.setHeader("ETag",__contentETag);
|
||||||
writer.write(__content);
|
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();
|
_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
|
@Test
|
||||||
public void testGzipHandler() throws Exception
|
public void testGzipHandler() throws Exception
|
||||||
{
|
{
|
||||||
|
@ -133,22 +175,65 @@ public class GzipHandlerTest
|
||||||
HttpTester.Response response;
|
HttpTester.Response response;
|
||||||
|
|
||||||
request.setMethod("GET");
|
request.setMethod("GET");
|
||||||
|
request.setURI("/ctx/content");
|
||||||
request.setVersion("HTTP/1.0");
|
request.setVersion("HTTP/1.0");
|
||||||
request.setHeader("Host","tester");
|
request.setHeader("Host","tester");
|
||||||
request.setHeader("accept-encoding","gzip");
|
request.setHeader("accept-encoding","gzip");
|
||||||
request.setURI("/ctx/content");
|
|
||||||
|
|
||||||
response = HttpTester.parseResponse(_connector.getResponses(request.generate()));
|
response = HttpTester.parseResponse(_connector.getResponses(request.generate()));
|
||||||
|
|
||||||
assertTrue(response.get("Content-Encoding").equalsIgnoreCase("gzip"));
|
assertThat(response.getStatus(),is(200));
|
||||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
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()));
|
InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
|
||||||
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
|
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
|
||||||
IO.copy(testIn,testOut);
|
IO.copy(testIn,testOut);
|
||||||
|
|
||||||
assertEquals(__content, testOut.toString("UTF8"));
|
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
|
@Test
|
||||||
|
@ -166,8 +251,10 @@ public class GzipHandlerTest
|
||||||
|
|
||||||
response = HttpTester.parseResponse(_connector.getResponses(request.generate()));
|
response = HttpTester.parseResponse(_connector.getResponses(request.generate()));
|
||||||
|
|
||||||
assertTrue(response.get("Content-Encoding").equalsIgnoreCase("gzip"));
|
assertThat(response.getStatus(),is(200));
|
||||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
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()));
|
InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
|
||||||
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
|
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
|
||||||
|
@ -190,9 +277,11 @@ public class GzipHandlerTest
|
||||||
request.setURI("/ctx/include");
|
request.setURI("/ctx/include");
|
||||||
|
|
||||||
response = HttpTester.parseResponse(_connector.getResponses(request.generate()));
|
response = HttpTester.parseResponse(_connector.getResponses(request.generate()));
|
||||||
|
|
||||||
assertTrue(response.get("Content-Encoding").equalsIgnoreCase("gzip"));
|
assertThat(response.getStatus(),is(200));
|
||||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
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()));
|
InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
|
||||||
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
|
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
|
||||||
|
|
Loading…
Reference in New Issue