Merge branch 'master' into jetty-8
This commit is contained in:
commit
3a0e9e1733
|
@ -18,16 +18,10 @@
|
|||
|
||||
package org.eclipse.jetty.osgi.boot;
|
||||
|
||||
import java.util.Dictionary;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import org.eclipse.jetty.deploy.App;
|
||||
import org.eclipse.jetty.deploy.bindings.StandardDeployer;
|
||||
import org.eclipse.jetty.deploy.graph.Node;
|
||||
import org.eclipse.jetty.osgi.boot.utils.EventSender;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -41,18 +35,27 @@ public class OSGiDeployer extends StandardDeployer
|
|||
/* ------------------------------------------------------------ */
|
||||
public void processBinding(Node node, App app) throws Exception
|
||||
{
|
||||
//TODO how to NOT send this event if its not a webapp!
|
||||
EventSender.getInstance().send(EventSender.DEPLOYING_EVENT, ((AbstractOSGiApp)app).getBundle(), app.getContextPath());
|
||||
try
|
||||
//TODO how to NOT send this event if its not a webapp:
|
||||
//OSGi Enterprise Spec only wants an event sent if its a webapp bundle (ie not a ContextHandler)
|
||||
if (!(app instanceof AbstractOSGiApp))
|
||||
{
|
||||
super.processBinding(node,app);
|
||||
((AbstractOSGiApp)app).registerAsOSGiService();
|
||||
EventSender.getInstance().send(EventSender.DEPLOYED_EVENT, ((AbstractOSGiApp)app).getBundle(), app.getContextPath());
|
||||
}
|
||||
catch (Exception e)
|
||||
else
|
||||
{
|
||||
EventSender.getInstance().send(EventSender.FAILED_EVENT, ((AbstractOSGiApp)app).getBundle(), app.getContextPath());
|
||||
throw e;
|
||||
EventSender.getInstance().send(EventSender.DEPLOYING_EVENT, ((AbstractOSGiApp)app).getBundle(), app.getContextPath());
|
||||
try
|
||||
{
|
||||
super.processBinding(node,app);
|
||||
((AbstractOSGiApp)app).registerAsOSGiService();
|
||||
EventSender.getInstance().send(EventSender.DEPLOYED_EVENT, ((AbstractOSGiApp)app).getBundle(), app.getContextPath());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
EventSender.getInstance().send(EventSender.FAILED_EVENT, ((AbstractOSGiApp)app).getBundle(), app.getContextPath());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -555,8 +555,9 @@ public abstract class AbstractHttpConnection extends AbstractConnection
|
|||
{
|
||||
if (error)
|
||||
{
|
||||
_endp.shutdownOutput();
|
||||
_generator.setPersistent(false);
|
||||
_generator.flushBuffer();
|
||||
_endp.shutdownOutput();
|
||||
if (!_generator.isComplete())
|
||||
_response.complete();
|
||||
}
|
||||
|
|
|
@ -106,6 +106,7 @@ public class GzipFilter extends UserAgentFilter
|
|||
private static final Logger LOG = Log.getLogger(GzipFilter.class);
|
||||
public final static String GZIP="gzip";
|
||||
public final static String DEFLATE="deflate";
|
||||
|
||||
|
||||
protected Set<String> _mimeTypes;
|
||||
protected int _bufferSize=8192;
|
||||
|
@ -116,6 +117,11 @@ public class GzipFilter extends UserAgentFilter
|
|||
protected Set<Pattern> _excludedAgentPatterns;
|
||||
protected Set<String> _excludedPaths;
|
||||
protected Set<Pattern> _excludedPathPatterns;
|
||||
|
||||
private static final int STATE_SEPARATOR = 0;
|
||||
private static final int STATE_Q = 1;
|
||||
private static final int STATE_QVALUE = 2;
|
||||
private static final int STATE_DEFAULT = 3;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -263,16 +269,90 @@ public class GzipFilter extends UserAgentFilter
|
|||
{
|
||||
// TODO, this could be a little more robust.
|
||||
// prefer gzip over deflate
|
||||
String compression = null;
|
||||
if (encodingHeader!=null)
|
||||
{
|
||||
if (encodingHeader.toLowerCase().contains(GZIP))
|
||||
return GZIP;
|
||||
else if (encodingHeader.toLowerCase().contains(DEFLATE))
|
||||
return DEFLATE;
|
||||
|
||||
String[] encodings = getEncodings(encodingHeader);
|
||||
if (encodings != null)
|
||||
{
|
||||
for (int i=0; i< encodings.length; i++)
|
||||
{
|
||||
if (encodings[i].toLowerCase().contains(GZIP))
|
||||
{
|
||||
if (isEncodingAcceptable(encodings[i]))
|
||||
{
|
||||
compression = GZIP;
|
||||
break; //prefer Gzip over deflate
|
||||
}
|
||||
}
|
||||
|
||||
if (encodings[i].toLowerCase().contains(DEFLATE))
|
||||
{
|
||||
if (isEncodingAcceptable(encodings[i]))
|
||||
{
|
||||
compression = DEFLATE; //Keep checking in case gzip is acceptable
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return compression;
|
||||
}
|
||||
|
||||
|
||||
private String[] getEncodings (String encodingHeader)
|
||||
{
|
||||
if (encodingHeader == null)
|
||||
return null;
|
||||
return encodingHeader.split(",");
|
||||
}
|
||||
|
||||
private boolean isEncodingAcceptable(String encoding)
|
||||
{
|
||||
int state = STATE_DEFAULT;
|
||||
int qvalueIdx = -1;
|
||||
for (int i=0;i<encoding.length();i++)
|
||||
{
|
||||
char c = encoding.charAt(i);
|
||||
switch (state)
|
||||
{
|
||||
case STATE_DEFAULT:
|
||||
{
|
||||
if (';' == c)
|
||||
state = STATE_SEPARATOR;
|
||||
break;
|
||||
}
|
||||
case STATE_SEPARATOR:
|
||||
{
|
||||
if ('q' == c || 'Q' == c)
|
||||
state = STATE_Q;
|
||||
break;
|
||||
}
|
||||
case STATE_Q:
|
||||
{
|
||||
if ('=' == c)
|
||||
state = STATE_QVALUE;
|
||||
break;
|
||||
}
|
||||
case STATE_QVALUE:
|
||||
{
|
||||
if (qvalueIdx < 0 && '0' == c || '1' == c)
|
||||
qvalueIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (qvalueIdx < 0)
|
||||
return true;
|
||||
|
||||
if ("0".equals(encoding.substring(qvalueIdx).trim()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, final String compressionType)
|
||||
{
|
||||
CompressedResponseWrapper wrappedResponse = null;
|
||||
|
|
|
@ -65,6 +65,10 @@ public class GzipFilterDefaultNoRecompressTest
|
|||
{ "jetty_logo.tiff", "image/tiff", GzipFilter.GZIP },
|
||||
{ "jetty_logo.xcf", "image/xcf", GzipFilter.GZIP },
|
||||
{ "jetty_logo.jp2", "image/jpeg2000", GzipFilter.GZIP },
|
||||
//qvalue disables compression
|
||||
{ "test_quotes.txt", "text/plain", GzipFilter.GZIP+";q=0"},
|
||||
{ "test_quotes.txt", "text/plain", GzipFilter.GZIP+"; q = 0 "},
|
||||
|
||||
|
||||
// Same tests again for deflate
|
||||
// Some already compressed files
|
||||
|
|
|
@ -123,6 +123,52 @@ public class GzipFilterDefaultTest
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsGzipCompressedTinyWithQ() throws Exception
|
||||
{
|
||||
GzipTester tester = new GzipTester(testingdir, compressionType+";q=0.5");
|
||||
|
||||
// Test content that is smaller than the buffer.
|
||||
int filesize = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE / 4;
|
||||
tester.prepareServerFile("file.txt",filesize);
|
||||
|
||||
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
|
||||
holder.setInitParameter("mimeTypes","text/plain");
|
||||
|
||||
try
|
||||
{
|
||||
tester.start();
|
||||
tester.assertIsResponseGzipCompressed("file.txt");
|
||||
}
|
||||
finally
|
||||
{
|
||||
tester.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsGzipCompressedTinyWithBadQ() throws Exception
|
||||
{
|
||||
GzipTester tester = new GzipTester(testingdir, compressionType+";q=");
|
||||
|
||||
// Test content that is smaller than the buffer.
|
||||
int filesize = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE / 4;
|
||||
tester.prepareServerFile("file.txt",filesize);
|
||||
|
||||
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
|
||||
holder.setInitParameter("mimeTypes","text/plain");
|
||||
|
||||
try
|
||||
{
|
||||
tester.start();
|
||||
tester.assertIsResponseGzipCompressed("file.txt");
|
||||
}
|
||||
finally
|
||||
{
|
||||
tester.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsGzipCompressedLarge() throws Exception
|
||||
{
|
||||
|
@ -146,6 +192,28 @@ public class GzipFilterDefaultTest
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsNotGzipCompressedWithQ() throws Exception
|
||||
{
|
||||
GzipTester tester = new GzipTester(testingdir, compressionType+"; q = 0");
|
||||
|
||||
int filesize = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE / 4;
|
||||
tester.prepareServerFile("file.txt",filesize);
|
||||
|
||||
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
|
||||
holder.setInitParameter("mimeTypes","text/plain");
|
||||
|
||||
try
|
||||
{
|
||||
tester.start();
|
||||
tester.assertIsResponseNotGzipCompressed("file.txt", filesize, HttpStatus.OK_200);
|
||||
}
|
||||
finally
|
||||
{
|
||||
tester.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsNotGzipCompressed() throws Exception
|
||||
{
|
||||
|
|
|
@ -102,9 +102,13 @@ public class GzipTester
|
|||
|
||||
// Assert the response headers
|
||||
Assert.assertThat("Response.method",response.getMethod(),nullValue());
|
||||
// Assert.assertThat("Response.status",response.getStatus(),is(HttpServletResponse.SC_OK));
|
||||
// Assert.assertThat("Response.status",response.getStatus(),is(HttpServletResponse.SC_OK));
|
||||
Assert.assertThat("Response.header[Content-Length]",response.getHeader("Content-Length"),notNullValue());
|
||||
Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),containsString(compressionType));
|
||||
int qindex = compressionType.indexOf(";");
|
||||
if (qindex < 0)
|
||||
Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),containsString(compressionType));
|
||||
else
|
||||
Assert.assertThat("Response.header[Content-Encoding]", response.getHeader("Content-Encoding"),containsString(compressionType.substring(0,qindex)));
|
||||
|
||||
// Assert that the decompressed contents are what we expect.
|
||||
File serverFile = testdir.getFile(serverFilename);
|
||||
|
@ -117,11 +121,11 @@ public class GzipTester
|
|||
try
|
||||
{
|
||||
bais = new ByteArrayInputStream(response.getContentBytes());
|
||||
if (compressionType.equals(GzipFilter.GZIP))
|
||||
if (compressionType.startsWith(GzipFilter.GZIP))
|
||||
{
|
||||
in = new GZIPInputStream(bais);
|
||||
}
|
||||
else if (compressionType.equals(GzipFilter.DEFLATE))
|
||||
else if (compressionType.startsWith(GzipFilter.DEFLATE))
|
||||
{
|
||||
in = new InflaterInputStream(bais, new Inflater(true));
|
||||
}
|
||||
|
@ -257,6 +261,7 @@ public class GzipTester
|
|||
Assert.assertEquals("Expected response equals actual response",expectedResponse,actual);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Asserts that the request results in a properly structured GzipFilter response, where the content is
|
||||
|
|
Loading…
Reference in New Issue