408909 GzipFilter setting of headers when reset and/or not compressed

updated some more test harnesses for etag tests
This commit is contained in:
Greg Wilkins 2013-05-27 17:48:08 +10:00
parent 16994cbd6c
commit 48c2a410b6
11 changed files with 10 additions and 271 deletions

View File

@ -135,7 +135,7 @@ public class GzipFilterContentLengthTest
{
tester.start();
HttpTester response = tester.assertIsResponseNotGzipCompressed("GET",testfile.getName(),filesize,HttpStatus.OK_200);
Assert.assertThat(response.getHeader("ETAG"),Matchers.startsWith("w/etag-"));
Assert.assertThat(response.getHeader("ETAG"),Matchers.startsWith("W/etag-"));
}
finally
{

View File

@ -1,263 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.servlets;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.servlets.gzip.Hex;
import org.eclipse.jetty.servlets.gzip.NoOpOutputStream;
import org.eclipse.jetty.toolchain.test.IO;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
/**
* Test the effects of Gzip filtering when in the context of HTTP/1.1 Pipelining.
*/
@RunWith(Parameterized.class)
public class GzipWithPipeliningTest
{
@Parameters
public static Collection<String[]> data()
{
// Test different Content-Encoding header combinations. So implicitly testing that gzip is preferred oder deflate
String[][] data = new String[][]
{
{ GzipFilter.GZIP },
{ GzipFilter.DEFLATE + ", " + GzipFilter.GZIP },
{ GzipFilter.GZIP + ", " + GzipFilter.DEFLATE },
{ GzipFilter.DEFLATE }
};
return Arrays.asList(data);
}
@Rule
public TestingDir testingdir = new TestingDir();
private Server server;
private URI serverUri;
private String encodingHeader;
public GzipWithPipeliningTest(String encodingHeader)
{
this.encodingHeader = encodingHeader;
}
@Before
public void startServer() throws Exception
{
// Configure Server
server = new Server(0);
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
DefaultServlet servlet = new DefaultServlet();
ServletHolder holder = new ServletHolder(servlet);
holder.setInitParameter("resourceBase",MavenTestingUtils.getTestResourcesDir().getAbsolutePath());
context.addServlet(holder,"/");
FilterHolder filter = context.addFilter(GzipFilter.class,"/*",0);
filter.setInitParameter("mimeTypes","text/plain");
server.setHandler(context);
// Start Server
server.start();
Connector conn = server.getConnectors()[0];
String host = conn.getHost();
if (host == null)
{
host = "localhost";
}
int port = conn.getLocalPort();
serverUri = new URI(String.format("ws://%s:%d/",host,port));
// System.out.printf("Server URI: %s%n",serverUri);
}
@After
public void stopServer() throws Exception
{
server.stop();
}
@Test
public void testGzipThenImagePipelining() throws Exception
{
testingdir.ensureEmpty();
File outputDir = testingdir.getDir();
PipelineHelper client = new PipelineHelper(serverUri, encodingHeader);
try
{
File txtFile = MavenTestingUtils.getTestResourceFile("lots-of-fantasy-names.txt");
File pngFile = MavenTestingUtils.getTestResourceFile("jetty_logo.png");
// Size of content, as it exists on disk, without gzip compression.
long rawsize = txtFile.length() + pngFile.length();
assertThat("Ensure that we have sufficient file size to trigger chunking",rawsize,greaterThan(300000L));
String respHeader;
client.connect();
// Request text that will be gzipped + chunked in the response
client.issueGET("/lots-of-fantasy-names.txt",true, false);
respHeader = client.readResponseHeader();
System.out.println("Response Header #1 --\n" + respHeader);
String expectedEncodingHeader = encodingHeader.equals(GzipFilter.DEFLATE) ? GzipFilter.DEFLATE : GzipFilter.GZIP;
assertThat("Content-Encoding should be gzipped",respHeader,containsString("Content-Encoding: " + expectedEncodingHeader + "\r\n"));
assertThat("Transfer-Encoding should be chunked",respHeader,containsString("Transfer-Encoding: chunked\r\n"));
// Raw output / gzipped, writted to disk (checked for sha1sum later)
File rawOutputFile = new File(outputDir, "response-1.gz");
FileOutputStream rawOutputStream = new FileOutputStream(rawOutputFile);
long chunkSize = client.readChunkSize();
System.out.println("Chunk Size: " + chunkSize);
// Read only 20% - intentionally a partial read.
System.out.println("Attempting to read partial content ...");
int readBytes = client.readBody(rawOutputStream,(int)(chunkSize * 0.20f));
System.out.printf("Read %,d bytes%n",readBytes);
// Issue another request
client.issueGET("/jetty_logo.png",true, false);
// Finish reading chunks
System.out.println("Finish reading remaining chunks ...");
String line;
chunkSize = chunkSize - readBytes;
while (chunkSize > 0)
{
readBytes = client.readBody(rawOutputStream,(int)chunkSize);
System.out.printf("Read %,d bytes%n",readBytes);
line = client.readLine();
assertThat("Chunk delim should be an empty line with CR+LF",line,is(""));
chunkSize = client.readChunkSize();
System.out.printf("Next Chunk: (0x%X) %,d bytes%n",chunkSize,chunkSize);
}
// Inter-pipeline delim
line = client.readLine();
assertThat("Inter-pipeline delim should be an empty line with CR+LF",line,is(""));
// Sha1tracking for 1st Request
MessageDigest digestTxt = MessageDigest.getInstance("SHA1");
DigestOutputStream digesterTxt = new DigestOutputStream(new NoOpOutputStream(),digestTxt);
// Decompress 1st request and calculate sha1sum
IO.close(rawOutputStream);
FileInputStream rawInputStream = new FileInputStream(rawOutputFile);
InputStream uncompressedStream = null;
if (GzipFilter.DEFLATE.equals(encodingHeader))
{
uncompressedStream = new InflaterInputStream(rawInputStream, new Inflater(true));
}
else
{
uncompressedStream = new GZIPInputStream(rawInputStream);
}
IO.copy(uncompressedStream, digesterTxt);
// Read 2nd request http response header
respHeader = client.readResponseHeader();
System.out.println("Response Header #2 --\n" + respHeader);
assertThat("Content-Encoding should NOT be gzipped",respHeader,not(containsString("Content-Encoding: gzip\r\n")));
assertThat("Transfer-Encoding should NOT be chunked",respHeader,not(containsString("Transfer-Encoding: chunked\r\n")));
// Sha1tracking for 2nd Request
MessageDigest digestImg = MessageDigest.getInstance("SHA1");
DigestOutputStream digesterImg = new DigestOutputStream(new NoOpOutputStream(),digestImg);
// Read 2nd request body
int contentLength = client.getContentLength(respHeader);
assertThat("Image Content Length",(long)contentLength,is(pngFile.length()));
client.readBody(digesterImg,contentLength);
// Validate checksums
IO.close(rawOutputStream);
assertChecksum("lots-of-fantasy-names.txt",digestTxt);
IO.close(digesterImg);
assertChecksum("jetty_logo.png",digestImg);
}
finally
{
client.disconnect();
}
}
private void assertChecksum(String testResourceFile, MessageDigest digest) throws IOException
{
String expectedSha1 = loadSha1sum(testResourceFile + ".sha1");
String actualSha1 = Hex.asHex(digest.digest());
assertEquals(testResourceFile + " / SHA1Sum of content",expectedSha1,actualSha1);
}
private String loadSha1sum(String testResourceSha1Sum) throws IOException
{
File sha1File = MavenTestingUtils.getTestResourceFile(testResourceSha1Sum);
String contents = IO.readToString(sha1File);
Pattern pat = Pattern.compile("^[0-9A-Fa-f]*");
Matcher mat = pat.matcher(contents);
assertTrue("Should have found HEX code in SHA1 file: " + sha1File,mat.find());
return mat.group();
}
}

View File

@ -192,7 +192,7 @@ public class GzipTester
Assert.assertThat(prefix + ".header[Content-Type] (should have a Content-Type associated with it)",response.getHeader("Content-Type"),notNullValue());
Assert.assertThat(prefix + ".header[Content-Type]",response.getHeader("Content-Type"),is(expectedContentType));
Assert.assertThat(response.getHeader("ETAG"),Matchers.startsWith("w/etag-"));
Assert.assertThat(response.getHeader("ETAG"),Matchers.startsWith("W/"));
ByteArrayInputStream bais = null;
DigestOutputStream digester = null;

View File

@ -51,6 +51,7 @@ public class TestMinGzipSizeServlet extends TestDirContentServlet
byte[] dataBytes = loadContentFileBytes(fileName);
response.setContentLength(dataBytes.length);
response.setHeader("ETag","W/etag-"+fileName);
if (fileName.endsWith(".js"))
{
// intentionally long-form content type to test ";" splitting in code

View File

@ -59,7 +59,7 @@ public class TestServletLengthStreamTypeWrite extends TestDirContentServlet
response.setContentType("text/plain");
else if (fileName.endsWith("mp3"))
response.setContentType("audio/mpeg");
response.setHeader("ETag","w/etag-"+fileName);
response.setHeader("ETag","W/etag-"+fileName);
out.write(dataBytes);
}

View File

@ -57,7 +57,7 @@ public class TestServletLengthTypeStreamWrite extends TestDirContentServlet
response.setContentType("text/plain");
else if (fileName.endsWith("mp3"))
response.setContentType("audio/mpeg");
response.setHeader("ETag","w/etag-"+fileName);
response.setHeader("ETag","W/etag-"+fileName);
ServletOutputStream out = response.getOutputStream();
out.write(dataBytes);

View File

@ -59,7 +59,7 @@ public class TestServletStreamLengthTypeWrite extends TestDirContentServlet
response.setContentType("text/plain");
else if (fileName.endsWith("mp3"))
response.setContentType("audio/mpeg");
response.setHeader("ETag","w/etag-"+fileName);
response.setHeader("ETag","W/etag-"+fileName);
out.write(dataBytes);
}

View File

@ -57,7 +57,7 @@ public class TestServletStreamTypeLengthWrite extends TestDirContentServlet
response.setContentType("text/plain");
else if (fileName.endsWith("mp3"))
response.setContentType("audio/mpeg");
response.setHeader("ETag","w/etag-"+fileName);
response.setHeader("ETag","W/etag-"+fileName);
response.setContentLength(dataBytes.length);

View File

@ -55,7 +55,7 @@ public class TestServletTypeLengthStreamWrite extends TestDirContentServlet
response.setContentType("text/plain");
else if (fileName.endsWith("mp3"))
response.setContentType("audio/mpeg");
response.setHeader("ETag","w/etag-"+fileName);
response.setHeader("ETag","W/etag-"+fileName);
response.setContentLength(dataBytes.length);

View File

@ -55,7 +55,7 @@ public class TestServletTypeStreamLengthWrite extends TestDirContentServlet
response.setContentType("text/plain");
else if (fileName.endsWith("mp3"))
response.setContentType("audio/mpeg");
response.setHeader("ETag","w/etag-"+fileName);
response.setHeader("ETag","W/etag-"+fileName);
ServletOutputStream out = response.getOutputStream();

View File

@ -68,6 +68,7 @@ public class TestStaticMimeTypeServlet extends TestDirContentServlet
byte[] dataBytes = loadContentFileBytes(fileName);
response.setContentLength(dataBytes.length);
response.setHeader("ETag","W/etag-"+fileName);
Buffer buf = mimeTypes.getMimeByExtension(fileName);
if (buf == null)