Merge
This commit is contained in:
commit
9521e1f124
12
VERSION.txt
12
VERSION.txt
|
@ -1,6 +1,6 @@
|
|||
jetty-7.6.3-SNAPSHOT
|
||||
|
||||
jetty-7.6.2.v20120302 - 02 March 2012
|
||||
jetty-7.6.2.v20120308 - 08 March 2012
|
||||
+ 370387 SafariWebsocketDraft0Test failure during build.
|
||||
+ 371168 Update ClientCrossContextSessionTest
|
||||
+ 372093 handle quotes in Require-Bundle manifest string
|
||||
|
@ -9,7 +9,17 @@ jetty-7.6.2.v20120302 - 02 March 2012
|
|||
will happen in the next major release (to avoid break implementers).
|
||||
+ 372487 JDBCSessionManager does not work with Oracle
|
||||
+ 372806 Command line should accept relative paths for xml config files
|
||||
+ 373037 jetty.server.Response.setContentLength(int) should not close a Writer
|
||||
when length=0
|
||||
+ 373162 add improved implementation for getParameterMap(), needs a test
|
||||
though and the existing setup doesn't seem like it would easily support the
|
||||
needed test so need to do that still
|
||||
+ 373306 Set default user agent extraction pattern for UserAgentFilter
|
||||
+ 373567 cert validation issue with ocsp and crldp always being enabled when
|
||||
validating turned on fixed
|
||||
+ JETTY-1409 GzipFilter will double-compress application/x-gzip content
|
||||
+ JETTY-1489 WebAppProvider attempts to deploy .svn folder
|
||||
+ JETTY-1494 .
|
||||
|
||||
jetty-7.6.1.v20120215 - 15 February 2012
|
||||
+ 369121 simplified test
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>example-jetty-embedded</artifactId>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-all-server</artifactId>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-all</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-client</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-plus</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-webapp</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-websocket</artifactId>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-aggregate-project</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-ajp</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-annotations</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -171,7 +171,7 @@ public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attri
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Set the ThreadPool.
|
||||
* The threadpool passed is added via {@link #addBean(Object)} so that
|
||||
* The threadpool passed is added via {@link #addBean(Object)} so that
|
||||
* it's lifecycle may be managed as a {@link AggregateLifeCycle}.
|
||||
* @param threadPool the threadPool to set
|
||||
*/
|
||||
|
@ -878,7 +878,7 @@ public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attri
|
|||
@Deprecated
|
||||
public void setProvider(String provider)
|
||||
{
|
||||
setProvider(provider);
|
||||
_sslContextFactory.setProvider(provider);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
|
|
@ -276,6 +276,11 @@ class SelectConnector extends AggregateLifeCycle implements HttpClient.Connector
|
|||
_endp.shutdownOutput();
|
||||
}
|
||||
|
||||
public void dispatch()
|
||||
{
|
||||
_endp.asyncDispatch();
|
||||
}
|
||||
|
||||
public void asyncDispatch()
|
||||
{
|
||||
_endp.asyncDispatch();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-continuation</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-deploy</artifactId>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>jetty-distribution</artifactId>
|
||||
<name>Jetty :: Distribution Assemblies</name>
|
||||
|
@ -103,6 +103,16 @@
|
|||
<outputDirectory>${assembly-directory}/webapps</outputDirectory>
|
||||
<destFileName>test.war</destFileName>
|
||||
</artifactItem>
|
||||
<artifactItem>
|
||||
<groupId>org.eclipse.jetty.spdy</groupId>
|
||||
<artifactId>spdy-jetty-http-webapp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>war</type>
|
||||
<overWrite>true</overWrite>
|
||||
<includes>**</includes>
|
||||
<outputDirectory>${assembly-directory}/webapps</outputDirectory>
|
||||
<destFileName>spdy.war</destFileName>
|
||||
</artifactItem>
|
||||
<artifactItem>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-start</artifactId>
|
||||
|
@ -124,12 +134,24 @@
|
|||
</goals>
|
||||
<configuration>
|
||||
<includeGroupIds>org.eclipse.jetty</includeGroupIds>
|
||||
<excludeGroupIds>org.eclipse.jetty.orbit</excludeGroupIds>
|
||||
<excludeGroupIds>org.eclipse.jetty.orbit,org.eclipse.jetty.spdy</excludeGroupIds>
|
||||
<excludeArtifactIds>jetty-all,jetty-start,jetty-monitor,jetty-jsp</excludeArtifactIds>
|
||||
<includeTypes>jar</includeTypes>
|
||||
<outputDirectory>${assembly-directory}/lib</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>copy-lib-spdy-deps</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<includeGroupIds>org.eclipse.jetty.spdy</includeGroupIds>
|
||||
<includeTypes>jar</includeTypes>
|
||||
<outputDirectory>${assembly-directory}/lib/spdy</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>copy-orbit-servlet-api-deps</id>
|
||||
<phase>generate-resources</phase>
|
||||
|
@ -222,7 +244,7 @@
|
|||
<goal>unpack-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<includeGroupIds>org.eclipse.jetty</includeGroupIds>
|
||||
<includeGroupIds>org.eclipse.jetty,org.eclipse.jetty.spdy</includeGroupIds>
|
||||
<classifier>config</classifier>
|
||||
<failOnMissingClassifierArtifact>false</failOnMissingClassifierArtifact>
|
||||
<excludes>META-INF/**</excludes>
|
||||
|
@ -398,6 +420,27 @@
|
|||
<artifactId>jetty-overlay-deployer</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.spdy</groupId>
|
||||
<artifactId>spdy-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.spdy</groupId>
|
||||
<artifactId>spdy-jetty</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.spdy</groupId>
|
||||
<artifactId>spdy-jetty-http</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.spdy</groupId>
|
||||
<artifactId>spdy-jetty-http-webapp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>war</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.aggregate</groupId>
|
||||
<artifactId>jetty-all</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-http-spi</artifactId>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-http</artifactId>
|
||||
|
|
|
@ -0,0 +1,345 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009-2009 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.http.gzip;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.util.ByteArrayOutputStream2;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Skeletal implementation of a CompressedStream. This class adds compression features to a ServletOutputStream and takes care of setting response headers, etc.
|
||||
* Major work and configuration is done here. Subclasses using different kinds of compression only have to implement the abstract methods doCompress() and
|
||||
* setContentEncoding() using the desired compression and setting the appropriate Content-Encoding header string.
|
||||
*/
|
||||
public abstract class AbstractCompressedStream extends ServletOutputStream
|
||||
{
|
||||
private final String _encoding;
|
||||
protected HttpServletRequest _request;
|
||||
protected HttpServletResponse _response;
|
||||
protected OutputStream _out;
|
||||
protected ByteArrayOutputStream2 _bOut;
|
||||
protected DeflaterOutputStream _compressedOutputStream;
|
||||
protected boolean _closed;
|
||||
protected int _bufferSize;
|
||||
protected int _minCompressSize;
|
||||
protected long _contentLength;
|
||||
protected boolean _doNotCompress;
|
||||
|
||||
/**
|
||||
* Instantiates a new compressed stream.
|
||||
*
|
||||
* @param request
|
||||
* the request
|
||||
* @param response
|
||||
* the response
|
||||
* @param contentLength
|
||||
* the content length
|
||||
* @param bufferSize
|
||||
* the buffer size
|
||||
* @param minCompressSize
|
||||
* the min compress size
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
public AbstractCompressedStream(String encoding,HttpServletRequest request, HttpServletResponse response, long contentLength, int bufferSize, int minCompressSize)
|
||||
throws IOException
|
||||
{
|
||||
_encoding=encoding;
|
||||
_request = request;
|
||||
_response = response;
|
||||
_contentLength = contentLength;
|
||||
_bufferSize = bufferSize;
|
||||
_minCompressSize = minCompressSize;
|
||||
if (minCompressSize == 0)
|
||||
doCompress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset buffer.
|
||||
*/
|
||||
public void resetBuffer()
|
||||
{
|
||||
if (_response.isCommitted())
|
||||
throw new IllegalStateException("Committed");
|
||||
_closed = false;
|
||||
_out = null;
|
||||
_bOut = null;
|
||||
if (_compressedOutputStream != null)
|
||||
_response.setHeader("Content-Encoding",null);
|
||||
_compressedOutputStream = null;
|
||||
_doNotCompress = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the content length.
|
||||
*
|
||||
* @param length
|
||||
* the new content length
|
||||
*/
|
||||
public void setContentLength(long length)
|
||||
{
|
||||
_contentLength = length;
|
||||
if (_doNotCompress && length >= 0)
|
||||
{
|
||||
if (_contentLength < Integer.MAX_VALUE)
|
||||
_response.setContentLength((int)_contentLength);
|
||||
else
|
||||
_response.setHeader("Content-Length",Long.toString(_contentLength));
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see java.io.OutputStream#flush()
|
||||
*/
|
||||
@Override
|
||||
public void flush() throws IOException
|
||||
{
|
||||
if (_out == null || _bOut != null)
|
||||
{
|
||||
if (_contentLength > 0 && _contentLength < _minCompressSize)
|
||||
doNotCompress();
|
||||
else
|
||||
doCompress();
|
||||
}
|
||||
|
||||
_out.flush();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see java.io.OutputStream#close()
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
if (_closed)
|
||||
return;
|
||||
|
||||
if (_request.getAttribute("javax.servlet.include.request_uri") != null)
|
||||
flush();
|
||||
else
|
||||
{
|
||||
if (_bOut != null)
|
||||
{
|
||||
if (_contentLength < 0)
|
||||
_contentLength = _bOut.getCount();
|
||||
if (_contentLength < _minCompressSize)
|
||||
doNotCompress();
|
||||
else
|
||||
doCompress();
|
||||
}
|
||||
else if (_out == null)
|
||||
{
|
||||
doNotCompress();
|
||||
}
|
||||
|
||||
if (_compressedOutputStream != null)
|
||||
_compressedOutputStream.close();
|
||||
else
|
||||
_out.close();
|
||||
_closed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish.
|
||||
*
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
public void finish() throws IOException
|
||||
{
|
||||
if (!_closed)
|
||||
{
|
||||
if (_out == null || _bOut != null)
|
||||
{
|
||||
if (_contentLength > 0 && _contentLength < _minCompressSize)
|
||||
doNotCompress();
|
||||
else
|
||||
doCompress();
|
||||
}
|
||||
|
||||
if (_compressedOutputStream != null && !_closed)
|
||||
{
|
||||
_closed = true;
|
||||
_compressedOutputStream.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see java.io.OutputStream#write(int)
|
||||
*/
|
||||
@Override
|
||||
public void write(int b) throws IOException
|
||||
{
|
||||
checkOut(1);
|
||||
_out.write(b);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see java.io.OutputStream#write(byte[])
|
||||
*/
|
||||
@Override
|
||||
public void write(byte b[]) throws IOException
|
||||
{
|
||||
checkOut(b.length);
|
||||
_out.write(b);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see java.io.OutputStream#write(byte[], int, int)
|
||||
*/
|
||||
@Override
|
||||
public void write(byte b[], int off, int len) throws IOException
|
||||
{
|
||||
checkOut(len);
|
||||
_out.write(b,off,len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do compress.
|
||||
*
|
||||
* @throws IOException Signals that an I/O exception has occurred.
|
||||
*/
|
||||
public void doCompress() throws IOException
|
||||
{
|
||||
if (_compressedOutputStream==null)
|
||||
{
|
||||
if (_response.isCommitted())
|
||||
throw new IllegalStateException();
|
||||
|
||||
setHeader("Content-Encoding", _encoding);
|
||||
|
||||
if (_response.containsHeader("Content-Encoding"))
|
||||
{
|
||||
_out=_compressedOutputStream=createStream();
|
||||
|
||||
if (_bOut!=null)
|
||||
{
|
||||
_out.write(_bOut.getBuf(),0,_bOut.getCount());
|
||||
_bOut=null;
|
||||
}
|
||||
}
|
||||
else
|
||||
doNotCompress();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not compress.
|
||||
*
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
public void doNotCompress() throws IOException
|
||||
{
|
||||
if (_compressedOutputStream != null)
|
||||
throw new IllegalStateException();
|
||||
if (_out == null || _bOut != null)
|
||||
{
|
||||
_doNotCompress = true;
|
||||
|
||||
_out = _response.getOutputStream();
|
||||
setContentLength(_contentLength);
|
||||
|
||||
if (_bOut != null)
|
||||
_out.write(_bOut.getBuf(),0,_bOut.getCount());
|
||||
_bOut = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check out.
|
||||
*
|
||||
* @param length
|
||||
* the length
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
private void checkOut(int length) throws IOException
|
||||
{
|
||||
if (_closed)
|
||||
throw new IOException("CLOSED");
|
||||
|
||||
if (_out == null)
|
||||
{
|
||||
if (_response.isCommitted() || (_contentLength >= 0 && _contentLength < _minCompressSize))
|
||||
doNotCompress();
|
||||
else if (length > _minCompressSize)
|
||||
doCompress();
|
||||
else
|
||||
_out = _bOut = new ByteArrayOutputStream2(_bufferSize);
|
||||
}
|
||||
else if (_bOut != null)
|
||||
{
|
||||
if (_response.isCommitted() || (_contentLength >= 0 && _contentLength < _minCompressSize))
|
||||
doNotCompress();
|
||||
else if (length >= (_bOut.getBuf().length - _bOut.getCount()))
|
||||
doCompress();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedStream#getOutputStream()
|
||||
*/
|
||||
public OutputStream getOutputStream()
|
||||
{
|
||||
return _out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedStream#isClosed()
|
||||
*/
|
||||
public boolean isClosed()
|
||||
{
|
||||
return _closed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows derived implementations to replace PrintWriter implementation.
|
||||
*/
|
||||
protected PrintWriter newWriter(OutputStream out, String encoding) throws UnsupportedEncodingException
|
||||
{
|
||||
return encoding == null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
|
||||
}
|
||||
|
||||
protected void setHeader(String name,String value)
|
||||
{
|
||||
_response.setHeader(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the stream fitting to the underlying compression type.
|
||||
*
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
protected abstract DeflaterOutputStream createStream() throws IOException;
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) Webtide LLC
|
||||
// Copyright (c) 2009-2009 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
|
||||
|
@ -11,7 +11,6 @@
|
|||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
|
||||
|
||||
package org.eclipse.jetty.http.gzip;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -28,42 +27,34 @@ import javax.servlet.http.HttpServletResponseWrapper;
|
|||
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*------------------------------------------------------------ */
|
||||
/**
|
||||
*/
|
||||
public class GzipResponseWrapper extends HttpServletResponseWrapper
|
||||
public abstract class CompressedResponseWrapper extends HttpServletResponseWrapper
|
||||
{
|
||||
public static final int DEFAULT_BUFFER_SIZE = 8192;
|
||||
public static final int DEFAULT_MIN_GZIP_SIZE = 256;
|
||||
|
||||
private HttpServletRequest _request;
|
||||
public static final int DEFAULT_BUFFER_SIZE = 8192;
|
||||
public static final int DEFAULT_MIN_COMPRESS_SIZE = 256;
|
||||
|
||||
private Set<String> _mimeTypes;
|
||||
private int _bufferSize=DEFAULT_BUFFER_SIZE;
|
||||
private int _minGzipSize=DEFAULT_MIN_GZIP_SIZE;
|
||||
private int _minCompressSize=DEFAULT_MIN_COMPRESS_SIZE;
|
||||
protected HttpServletRequest _request;
|
||||
|
||||
private PrintWriter _writer;
|
||||
private GzipStream _gzStream;
|
||||
private AbstractCompressedStream _compressedStream;
|
||||
private long _contentLength=-1;
|
||||
private boolean _noGzip;
|
||||
private boolean _noCompression;
|
||||
|
||||
/**
|
||||
* Instantiates a new gzip response wrapper.
|
||||
*
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
*/
|
||||
public GzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
|
||||
public CompressedResponseWrapper(HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
super(response);
|
||||
_request=request;
|
||||
_request = request;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Sets the mime types.
|
||||
*
|
||||
* @param mimeTypes the new mime types
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setMimeTypes(java.util.Set)
|
||||
*/
|
||||
public void setMimeTypes(Set<String> mimeTypes)
|
||||
{
|
||||
|
@ -72,8 +63,9 @@ public class GzipResponseWrapper extends HttpServletResponseWrapper
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see javax.servlet.ServletResponseWrapper#setBufferSize(int)
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setBufferSize(int)
|
||||
*/
|
||||
@Override
|
||||
public void setBufferSize(int bufferSize)
|
||||
{
|
||||
_bufferSize = bufferSize;
|
||||
|
@ -81,64 +73,66 @@ public class GzipResponseWrapper extends HttpServletResponseWrapper
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Sets the min gzip size.
|
||||
*
|
||||
* @param minGzipSize the new min gzip size
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setMinCompressSize(int)
|
||||
*/
|
||||
public void setMinGzipSize(int minGzipSize)
|
||||
public void setMinCompressSize(int minCompressSize)
|
||||
{
|
||||
_minGzipSize = minGzipSize;
|
||||
_minCompressSize = minCompressSize;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see javax.servlet.ServletResponseWrapper#setContentType(java.lang.String)
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setContentType(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void setContentType(String ct)
|
||||
{
|
||||
super.setContentType(ct);
|
||||
|
||||
|
||||
if (ct!=null)
|
||||
{
|
||||
int colon=ct.indexOf(";");
|
||||
if (colon>0)
|
||||
ct=ct.substring(0,colon);
|
||||
}
|
||||
|
||||
if ((_gzStream==null || _gzStream._out==null) &&
|
||||
|
||||
if ((_compressedStream==null || _compressedStream.getOutputStream()==null) &&
|
||||
(_mimeTypes==null && ct!=null && ct.contains("gzip") ||
|
||||
_mimeTypes!=null && (ct==null||!_mimeTypes.contains(StringUtil.asciiToLowerCase(ct)))))
|
||||
{
|
||||
noGzip();
|
||||
noCompression();
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServletResponseWrapper#setStatus(int, java.lang.String)
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setStatus(int, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void setStatus(int sc, String sm)
|
||||
{
|
||||
super.setStatus(sc,sm);
|
||||
if (sc<200 || sc==204 || sc==205 || sc>=300)
|
||||
noGzip();
|
||||
noCompression();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServletResponseWrapper#setStatus(int)
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setStatus(int)
|
||||
*/
|
||||
@Override
|
||||
public void setStatus(int sc)
|
||||
{
|
||||
super.setStatus(sc);
|
||||
if (sc<200 || sc==204 || sc==205 ||sc>=300)
|
||||
noGzip();
|
||||
noCompression();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see javax.servlet.ServletResponseWrapper#setContentLength(int)
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setContentLength(int)
|
||||
*/
|
||||
@Override
|
||||
public void setContentLength(int length)
|
||||
{
|
||||
setContentLength((long)length);
|
||||
|
@ -148,9 +142,9 @@ public class GzipResponseWrapper extends HttpServletResponseWrapper
|
|||
protected void setContentLength(long length)
|
||||
{
|
||||
_contentLength=length;
|
||||
if (_gzStream!=null)
|
||||
_gzStream.setContentLength(length);
|
||||
else if (_noGzip && _contentLength>=0)
|
||||
if (_compressedStream!=null)
|
||||
_compressedStream.setContentLength(length);
|
||||
else if (_noCompression && _contentLength>=0)
|
||||
{
|
||||
HttpServletResponse response = (HttpServletResponse)getResponse();
|
||||
if(_contentLength<Integer.MAX_VALUE)
|
||||
|
@ -166,15 +160,16 @@ public class GzipResponseWrapper extends HttpServletResponseWrapper
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServletResponseWrapper#addHeader(java.lang.String, java.lang.String)
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#addHeader(java.lang.String, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void addHeader(String name, String value)
|
||||
{
|
||||
if ("content-length".equalsIgnoreCase(name))
|
||||
{
|
||||
_contentLength=Long.parseLong(value);
|
||||
if (_gzStream!=null)
|
||||
_gzStream.setContentLength(_contentLength);
|
||||
if (_compressedStream!=null)
|
||||
_compressedStream.setContentLength(_contentLength);
|
||||
}
|
||||
else if ("content-type".equalsIgnoreCase(name))
|
||||
{
|
||||
|
@ -185,7 +180,7 @@ public class GzipResponseWrapper extends HttpServletResponseWrapper
|
|||
super.addHeader(name,value);
|
||||
if (!isCommitted())
|
||||
{
|
||||
noGzip();
|
||||
noCompression();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -194,8 +189,119 @@ public class GzipResponseWrapper extends HttpServletResponseWrapper
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServletResponseWrapper#setHeader(java.lang.String, java.lang.String)
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#flushBuffer()
|
||||
*/
|
||||
@Override
|
||||
public void flushBuffer() throws IOException
|
||||
{
|
||||
if (_writer!=null)
|
||||
_writer.flush();
|
||||
if (_compressedStream!=null)
|
||||
_compressedStream.finish();
|
||||
else
|
||||
getResponse().flushBuffer();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#reset()
|
||||
*/
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
super.reset();
|
||||
if (_compressedStream!=null)
|
||||
_compressedStream.resetBuffer();
|
||||
_writer=null;
|
||||
_compressedStream=null;
|
||||
_noCompression=false;
|
||||
_contentLength=-1;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#resetBuffer()
|
||||
*/
|
||||
@Override
|
||||
public void resetBuffer()
|
||||
{
|
||||
super.resetBuffer();
|
||||
if (_compressedStream!=null)
|
||||
_compressedStream.resetBuffer();
|
||||
_writer=null;
|
||||
_compressedStream=null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#sendError(int, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void sendError(int sc, String msg) throws IOException
|
||||
{
|
||||
resetBuffer();
|
||||
super.sendError(sc,msg);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#sendError(int)
|
||||
*/
|
||||
@Override
|
||||
public void sendError(int sc) throws IOException
|
||||
{
|
||||
resetBuffer();
|
||||
super.sendError(sc);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#sendRedirect(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void sendRedirect(String location) throws IOException
|
||||
{
|
||||
resetBuffer();
|
||||
super.sendRedirect(location);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#noCompression()
|
||||
*/
|
||||
public void noCompression()
|
||||
{
|
||||
_noCompression=true;
|
||||
if (_compressedStream!=null)
|
||||
{
|
||||
try
|
||||
{
|
||||
_compressedStream.doNotCompress();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#finish()
|
||||
*/
|
||||
public void finish() throws IOException
|
||||
{
|
||||
if (_writer!=null && !_compressedStream.isClosed())
|
||||
_writer.flush();
|
||||
if (_compressedStream!=null)
|
||||
_compressedStream.finish();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setHeader(java.lang.String, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void setHeader(String name, String value)
|
||||
{
|
||||
if ("content-length".equalsIgnoreCase(name))
|
||||
|
@ -211,197 +317,77 @@ public class GzipResponseWrapper extends HttpServletResponseWrapper
|
|||
super.setHeader(name,value);
|
||||
if (!isCommitted())
|
||||
{
|
||||
noGzip();
|
||||
noCompression();
|
||||
}
|
||||
}
|
||||
else
|
||||
super.setHeader(name,value);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServletResponseWrapper#setIntHeader(java.lang.String, int)
|
||||
*/
|
||||
public void setIntHeader(String name, int value)
|
||||
{
|
||||
if ("content-length".equalsIgnoreCase(name))
|
||||
{
|
||||
_contentLength=value;
|
||||
if (_gzStream!=null)
|
||||
_gzStream.setContentLength(_contentLength);
|
||||
}
|
||||
else
|
||||
super.setIntHeader(name,value);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see javax.servlet.ServletResponseWrapper#flushBuffer()
|
||||
*/
|
||||
public void flushBuffer() throws IOException
|
||||
{
|
||||
if (_writer!=null)
|
||||
_writer.flush();
|
||||
if (_gzStream!=null)
|
||||
_gzStream.finish();
|
||||
else
|
||||
getResponse().flushBuffer();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see javax.servlet.ServletResponseWrapper#reset()
|
||||
*/
|
||||
public void reset()
|
||||
{
|
||||
super.reset();
|
||||
if (_gzStream!=null)
|
||||
_gzStream.resetBuffer();
|
||||
_writer=null;
|
||||
_gzStream=null;
|
||||
_noGzip=false;
|
||||
_contentLength=-1;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see javax.servlet.ServletResponseWrapper#resetBuffer()
|
||||
*/
|
||||
public void resetBuffer()
|
||||
{
|
||||
super.resetBuffer();
|
||||
if (_gzStream!=null)
|
||||
_gzStream.resetBuffer();
|
||||
_writer=null;
|
||||
_gzStream=null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServletResponseWrapper#sendError(int, java.lang.String)
|
||||
*/
|
||||
public void sendError(int sc, String msg) throws IOException
|
||||
{
|
||||
resetBuffer();
|
||||
super.sendError(sc,msg);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServletResponseWrapper#sendError(int)
|
||||
*/
|
||||
public void sendError(int sc) throws IOException
|
||||
{
|
||||
resetBuffer();
|
||||
super.sendError(sc);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServletResponseWrapper#sendRedirect(java.lang.String)
|
||||
*/
|
||||
public void sendRedirect(String location) throws IOException
|
||||
{
|
||||
resetBuffer();
|
||||
super.sendRedirect(location);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see javax.servlet.ServletResponseWrapper#getOutputStream()
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#getOutputStream()
|
||||
*/
|
||||
@Override
|
||||
public ServletOutputStream getOutputStream() throws IOException
|
||||
{
|
||||
if (_gzStream==null)
|
||||
if (_compressedStream==null)
|
||||
{
|
||||
if (getResponse().isCommitted() || _noGzip)
|
||||
if (getResponse().isCommitted() || _noCompression)
|
||||
{
|
||||
setContentLength(_contentLength);
|
||||
return getResponse().getOutputStream();
|
||||
}
|
||||
|
||||
_gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
|
||||
_compressedStream=newCompressedStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minCompressSize);
|
||||
}
|
||||
else if (_writer!=null)
|
||||
throw new IllegalStateException("getWriter() called");
|
||||
|
||||
return _gzStream;
|
||||
return (ServletOutputStream)_compressedStream;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see javax.servlet.ServletResponseWrapper#getWriter()
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#getWriter()
|
||||
*/
|
||||
@Override
|
||||
public PrintWriter getWriter() throws IOException
|
||||
{
|
||||
if (_writer==null)
|
||||
{
|
||||
if (_gzStream!=null)
|
||||
if (_compressedStream!=null)
|
||||
throw new IllegalStateException("getOutputStream() called");
|
||||
|
||||
if (getResponse().isCommitted() || _noGzip)
|
||||
if (getResponse().isCommitted() || _noCompression)
|
||||
{
|
||||
setContentLength(_contentLength);
|
||||
return getResponse().getWriter();
|
||||
}
|
||||
|
||||
_gzStream=newGzipStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minGzipSize);
|
||||
_writer=newWriter(_gzStream,getCharacterEncoding());
|
||||
_compressedStream=newCompressedStream(_request,(HttpServletResponse)getResponse(),_contentLength,_bufferSize,_minCompressSize);
|
||||
_writer=newWriter((OutputStream)_compressedStream,getCharacterEncoding());
|
||||
}
|
||||
return _writer;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* No gzip.
|
||||
*/
|
||||
public void noGzip()
|
||||
{
|
||||
_noGzip=true;
|
||||
if (_gzStream!=null)
|
||||
{
|
||||
try
|
||||
{
|
||||
_gzStream.doNotGzip();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Finish.
|
||||
*
|
||||
* @throws IOException Signals that an I/O exception has occurred.
|
||||
* @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setIntHeader(java.lang.String, int)
|
||||
*/
|
||||
public void finish() throws IOException
|
||||
@Override
|
||||
public void setIntHeader(String name, int value)
|
||||
{
|
||||
if (_writer!=null && !_gzStream._closed)
|
||||
_writer.flush();
|
||||
if (_gzStream!=null)
|
||||
_gzStream.finish();
|
||||
if ("content-length".equalsIgnoreCase(name))
|
||||
{
|
||||
_contentLength=value;
|
||||
if (_compressedStream!=null)
|
||||
_compressedStream.setContentLength(_contentLength);
|
||||
}
|
||||
else
|
||||
super.setIntHeader(name,value);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Allows derived implementations to replace GzipStream implementation.
|
||||
*
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param contentLength the content length
|
||||
* @param bufferSize the buffer size
|
||||
* @param minGzipSize the min gzip size
|
||||
* @return the gzip stream
|
||||
* @throws IOException Signals that an I/O exception has occurred.
|
||||
*/
|
||||
protected GzipStream newGzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
|
||||
{
|
||||
return new GzipStream(request,response,contentLength,bufferSize,minGzipSize);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Allows derived implementations to replace PrintWriter implementation.
|
||||
|
@ -415,5 +401,11 @@ public class GzipResponseWrapper extends HttpServletResponseWrapper
|
|||
{
|
||||
return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
*@return the underlying CompressedStream implementation
|
||||
*/
|
||||
protected abstract AbstractCompressedStream newCompressedStream(HttpServletRequest _request, HttpServletResponse response, long _contentLength2, int _bufferSize2, int _minCompressedSize2) throws IOException;
|
||||
|
||||
}
|
|
@ -1,305 +0,0 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) Webtide LLC
|
||||
// ------------------------------------------------------------------------
|
||||
// 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.http.gzip;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.util.ByteArrayOutputStream2;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
*/
|
||||
public class GzipStream extends ServletOutputStream
|
||||
{
|
||||
protected HttpServletRequest _request;
|
||||
protected HttpServletResponse _response;
|
||||
protected OutputStream _out;
|
||||
protected ByteArrayOutputStream2 _bOut;
|
||||
protected GZIPOutputStream _gzOut;
|
||||
protected boolean _closed;
|
||||
protected int _bufferSize;
|
||||
protected int _minGzipSize;
|
||||
protected long _contentLength;
|
||||
protected boolean _doNotGzip;
|
||||
|
||||
/**
|
||||
* Instantiates a new gzip stream.
|
||||
*
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param contentLength the content length
|
||||
* @param bufferSize the buffer size
|
||||
* @param minGzipSize the min gzip size
|
||||
* @throws IOException Signals that an I/O exception has occurred.
|
||||
*/
|
||||
public GzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
|
||||
{
|
||||
_request=request;
|
||||
_response=response;
|
||||
_contentLength=contentLength;
|
||||
_bufferSize=bufferSize;
|
||||
_minGzipSize=minGzipSize;
|
||||
if (minGzipSize==0)
|
||||
doGzip();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset buffer.
|
||||
*/
|
||||
public void resetBuffer()
|
||||
{
|
||||
if (_response.isCommitted())
|
||||
throw new IllegalStateException("Committed");
|
||||
_closed=false;
|
||||
_out=null;
|
||||
_bOut=null;
|
||||
if (_gzOut!=null)
|
||||
_response.setHeader("Content-Encoding",null);
|
||||
_gzOut=null;
|
||||
_doNotGzip=false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the content length.
|
||||
*
|
||||
* @param length the new content length
|
||||
*/
|
||||
public void setContentLength(long length)
|
||||
{
|
||||
_contentLength=length;
|
||||
if (_doNotGzip && length>=0)
|
||||
{
|
||||
if(_contentLength<Integer.MAX_VALUE)
|
||||
_response.setContentLength((int)_contentLength);
|
||||
else
|
||||
_response.setHeader("Content-Length",Long.toString(_contentLength));
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see java.io.OutputStream#flush()
|
||||
*/
|
||||
public void flush() throws IOException
|
||||
{
|
||||
if (_out==null || _bOut!=null)
|
||||
{
|
||||
if (_contentLength>0 && _contentLength<_minGzipSize)
|
||||
doNotGzip();
|
||||
else
|
||||
doGzip();
|
||||
}
|
||||
|
||||
_out.flush();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see java.io.OutputStream#close()
|
||||
*/
|
||||
public void close() throws IOException
|
||||
{
|
||||
if (_closed)
|
||||
return;
|
||||
|
||||
if (_request.getAttribute("javax.servlet.include.request_uri")!=null)
|
||||
flush();
|
||||
else
|
||||
{
|
||||
if (_bOut!=null)
|
||||
{
|
||||
if (_contentLength<0)
|
||||
_contentLength=_bOut.getCount();
|
||||
if (_contentLength<_minGzipSize)
|
||||
doNotGzip();
|
||||
else
|
||||
doGzip();
|
||||
}
|
||||
else if (_out==null)
|
||||
{
|
||||
doNotGzip();
|
||||
}
|
||||
|
||||
if (_gzOut!=null)
|
||||
_gzOut.close();
|
||||
else
|
||||
_out.close();
|
||||
_closed=true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish.
|
||||
*
|
||||
* @throws IOException Signals that an I/O exception has occurred.
|
||||
*/
|
||||
public void finish() throws IOException
|
||||
{
|
||||
if (!_closed)
|
||||
{
|
||||
if (_out==null || _bOut!=null)
|
||||
{
|
||||
if (_contentLength>0 && _contentLength<_minGzipSize)
|
||||
doNotGzip();
|
||||
else
|
||||
doGzip();
|
||||
}
|
||||
|
||||
if (_gzOut!=null && !_closed)
|
||||
{
|
||||
_closed=true;
|
||||
_gzOut.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see java.io.OutputStream#write(int)
|
||||
*/
|
||||
public void write(int b) throws IOException
|
||||
{
|
||||
checkOut(1);
|
||||
_out.write(b);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see java.io.OutputStream#write(byte[])
|
||||
*/
|
||||
public void write(byte b[]) throws IOException
|
||||
{
|
||||
checkOut(b.length);
|
||||
_out.write(b);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see java.io.OutputStream#write(byte[], int, int)
|
||||
*/
|
||||
public void write(byte b[], int off, int len) throws IOException
|
||||
{
|
||||
checkOut(len);
|
||||
_out.write(b,off,len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the content encoding gzip.
|
||||
*
|
||||
* @return true, if successful
|
||||
*/
|
||||
protected boolean setContentEncodingGzip()
|
||||
{
|
||||
_response.setHeader("Content-Encoding", "gzip");
|
||||
return _response.containsHeader("Content-Encoding");
|
||||
}
|
||||
|
||||
/**
|
||||
* Do gzip.
|
||||
*
|
||||
* @throws IOException Signals that an I/O exception has occurred.
|
||||
*/
|
||||
public void doGzip() throws IOException
|
||||
{
|
||||
if (_gzOut==null)
|
||||
{
|
||||
if (_response.isCommitted())
|
||||
throw new IllegalStateException();
|
||||
|
||||
if (setContentEncodingGzip())
|
||||
{
|
||||
_out=_gzOut=new GZIPOutputStream(_response.getOutputStream(),_bufferSize);
|
||||
|
||||
if (_bOut!=null)
|
||||
{
|
||||
_out.write(_bOut.getBuf(),0,_bOut.getCount());
|
||||
_bOut=null;
|
||||
}
|
||||
}
|
||||
else
|
||||
doNotGzip();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not gzip.
|
||||
*
|
||||
* @throws IOException Signals that an I/O exception has occurred.
|
||||
*/
|
||||
public void doNotGzip() throws IOException
|
||||
{
|
||||
if (_gzOut!=null)
|
||||
throw new IllegalStateException();
|
||||
if (_out==null || _bOut!=null )
|
||||
{
|
||||
_doNotGzip = true;
|
||||
|
||||
_out=_response.getOutputStream();
|
||||
setContentLength(_contentLength);
|
||||
|
||||
if (_bOut!=null)
|
||||
_out.write(_bOut.getBuf(),0,_bOut.getCount());
|
||||
_bOut=null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check out.
|
||||
*
|
||||
* @param length the length
|
||||
* @throws IOException Signals that an I/O exception has occurred.
|
||||
*/
|
||||
private void checkOut(int length) throws IOException
|
||||
{
|
||||
if (_closed)
|
||||
throw new IOException("CLOSED");
|
||||
|
||||
if (_out==null)
|
||||
{
|
||||
if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize))
|
||||
doNotGzip();
|
||||
else if (length>_minGzipSize)
|
||||
doGzip();
|
||||
else
|
||||
_out=_bOut=new ByteArrayOutputStream2(_bufferSize);
|
||||
}
|
||||
else if (_bOut!=null)
|
||||
{
|
||||
if (_response.isCommitted() || (_contentLength>=0 && _contentLength<_minGzipSize))
|
||||
doNotGzip();
|
||||
else if (length>=(_bOut.getBuf().length -_bOut.getCount()))
|
||||
doGzip();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows derived implementations to replace PrintWriter implementation.
|
||||
*/
|
||||
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
|
||||
{
|
||||
return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-io</artifactId>
|
||||
|
|
|
@ -19,7 +19,14 @@ public interface AsyncEndPoint extends ConnectedEndPoint
|
|||
{
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Dispatch the endpoint to a thread to attend to it.
|
||||
* Dispatch the endpoint if it is not already dispatched
|
||||
*
|
||||
*/
|
||||
public void dispatch();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Dispatch the endpoint. If it is already dispatched, schedule a redispatch
|
||||
*
|
||||
*/
|
||||
public void asyncDispatch();
|
||||
|
|
|
@ -280,24 +280,17 @@ public class ChannelEndPoint implements EndPoint
|
|||
if (buf instanceof NIOBuffer)
|
||||
{
|
||||
final NIOBuffer nbuf = (NIOBuffer)buf;
|
||||
final ByteBuffer bbuf=nbuf.getByteBuffer();
|
||||
|
||||
//noinspection SynchronizationOnLocalVariableOrMethodParameter
|
||||
synchronized(bbuf)
|
||||
final ByteBuffer bbuf=nbuf.getByteBuffer().asReadOnlyBuffer();
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
bbuf.position(buffer.getIndex());
|
||||
bbuf.limit(buffer.putIndex());
|
||||
len=_channel.write(bbuf);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (len>0)
|
||||
buffer.skip(len);
|
||||
bbuf.position(0);
|
||||
bbuf.limit(bbuf.capacity());
|
||||
}
|
||||
bbuf.position(buffer.getIndex());
|
||||
bbuf.limit(buffer.putIndex());
|
||||
len=_channel.write(bbuf);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (len>0)
|
||||
buffer.skip(len);
|
||||
}
|
||||
}
|
||||
else if (buf instanceof RandomAccessFileBuffer)
|
||||
|
@ -363,46 +356,29 @@ public class ChannelEndPoint implements EndPoint
|
|||
|
||||
synchronized(this)
|
||||
{
|
||||
// We must sync because buffers may be shared (eg nbuf1 is likely to be cached content).
|
||||
//noinspection SynchronizationOnLocalVariableOrMethodParameter
|
||||
synchronized(bbuf0)
|
||||
// Adjust position indexs of buf0 and buf1
|
||||
bbuf0=bbuf0.asReadOnlyBuffer();
|
||||
bbuf0.position(header.getIndex());
|
||||
bbuf0.limit(header.putIndex());
|
||||
bbuf1=bbuf1.asReadOnlyBuffer();
|
||||
bbuf1.position(buffer.getIndex());
|
||||
bbuf1.limit(buffer.putIndex());
|
||||
|
||||
_gather2[0]=bbuf0;
|
||||
_gather2[1]=bbuf1;
|
||||
|
||||
// do the gathering write.
|
||||
length=(int)((GatheringByteChannel)_channel).write(_gather2);
|
||||
|
||||
int hl=header.length();
|
||||
if (length>hl)
|
||||
{
|
||||
//noinspection SynchronizationOnLocalVariableOrMethodParameter
|
||||
synchronized(bbuf1)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Adjust position indexs of buf0 and buf1
|
||||
bbuf0.position(header.getIndex());
|
||||
bbuf0.limit(header.putIndex());
|
||||
bbuf1.position(buffer.getIndex());
|
||||
bbuf1.limit(buffer.putIndex());
|
||||
|
||||
_gather2[0]=bbuf0;
|
||||
_gather2[1]=bbuf1;
|
||||
|
||||
// do the gathering write.
|
||||
length=(int)((GatheringByteChannel)_channel).write(_gather2);
|
||||
|
||||
int hl=header.length();
|
||||
if (length>hl)
|
||||
{
|
||||
header.clear();
|
||||
buffer.skip(length-hl);
|
||||
}
|
||||
else if (length>0)
|
||||
{
|
||||
header.skip(length);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
bbuf0.position(0);
|
||||
bbuf1.position(0);
|
||||
bbuf0.limit(bbuf0.capacity());
|
||||
bbuf1.limit(bbuf1.capacity());
|
||||
}
|
||||
}
|
||||
header.clear();
|
||||
buffer.skip(length-hl);
|
||||
}
|
||||
else if (length>0)
|
||||
{
|
||||
header.skip(length);
|
||||
}
|
||||
}
|
||||
return length;
|
||||
|
|
|
@ -37,6 +37,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
|
|||
{
|
||||
public static final Logger LOG=Log.getLogger("org.eclipse.jetty.io.nio");
|
||||
|
||||
private final boolean WORK_AROUND_JVM_BUG_6346658 = System.getProperty("os.name").toLowerCase().contains("win");
|
||||
private final SelectorManager.SelectSet _selectSet;
|
||||
private final SelectorManager _manager;
|
||||
private SelectionKey _key;
|
||||
|
@ -208,11 +209,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
|
|||
{
|
||||
synchronized(this)
|
||||
{
|
||||
if (_dispatched)
|
||||
{
|
||||
throw new IllegalStateException("dispatched");
|
||||
}
|
||||
else
|
||||
if (!_dispatched)
|
||||
{
|
||||
_dispatched = true;
|
||||
boolean dispatched = _manager.dispatch(_handler);
|
||||
|
@ -685,15 +682,23 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
|
|||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
try
|
||||
// On unix systems there is a JVM issue that if you cancel before closing, it can
|
||||
// cause the selector to block waiting for a channel to close and that channel can
|
||||
// block waiting for the remote end. But on windows, if you don't cancel before a
|
||||
// close, then the selector can block anyway!
|
||||
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=357318
|
||||
if (WORK_AROUND_JVM_BUG_6346658)
|
||||
{
|
||||
SelectionKey key = _key;
|
||||
if (key!=null)
|
||||
key.cancel();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
LOG.ignore(e);
|
||||
try
|
||||
{
|
||||
SelectionKey key = _key;
|
||||
if (key!=null)
|
||||
key.cancel();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
LOG.ignore(e);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
|
|
|
@ -237,6 +237,9 @@ public class SslConnection extends AbstractConnection implements AsyncConnection
|
|||
/* ------------------------------------------------------------ */
|
||||
public void onClose()
|
||||
{
|
||||
Connection connection = _sslEndPoint.getConnection();
|
||||
if (connection != null && connection != this)
|
||||
connection.onClose();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -408,8 +411,8 @@ public class SslConnection extends AbstractConnection implements AsyncConnection
|
|||
}
|
||||
|
||||
// If we are reading into the temp buffer and it has some content, then we should be dispatched.
|
||||
if (toFill==_unwrapBuf && _unwrapBuf.hasContent())
|
||||
_aEndp.asyncDispatch();
|
||||
if (toFill==_unwrapBuf && _unwrapBuf.hasContent() && !_connection.isSuspended())
|
||||
_aEndp.dispatch();
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -550,7 +553,7 @@ public class SslConnection extends AbstractConnection implements AsyncConnection
|
|||
break;
|
||||
|
||||
case BUFFER_OVERFLOW:
|
||||
_logger.debug("{} unwrap {} {}->{}",_session,result.getStatus(),_inbound.toDetailString(),buffer.toDetailString());
|
||||
if (_logger.isDebugEnabled()) _logger.debug("{} unwrap {} {}->{}",_session,result.getStatus(),_inbound.toDetailString(),buffer.toDetailString());
|
||||
break;
|
||||
|
||||
case OK:
|
||||
|
@ -718,6 +721,11 @@ public class SslConnection extends AbstractConnection implements AsyncConnection
|
|||
process(null, null);
|
||||
}
|
||||
|
||||
public void dispatch()
|
||||
{
|
||||
_aEndp.dispatch();
|
||||
}
|
||||
|
||||
public void asyncDispatch()
|
||||
{
|
||||
_aEndp.asyncDispatch();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jaspi</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jmx</artifactId>
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
-->
|
||||
<!--
|
||||
<Call name="createRegistry" class="java.rmi.registry.LocateRegistry">
|
||||
<Arg type="java.lang.Integer">1099</Arg>
|
||||
<Arg type="java.lang.Integer"><SystemProperty name="jetty.jmxrmiport" default="1099"/></Arg>
|
||||
<Call name="sleep" class="java.lang.Thread">
|
||||
<Arg type="java.lang.Integer">1000</Arg>
|
||||
</Call>
|
||||
|
@ -91,11 +91,11 @@
|
|||
<New class="javax.management.remote.JMXServiceURL">
|
||||
<Arg type="java.lang.String">rmi</Arg>
|
||||
<Arg type="java.lang.String" />
|
||||
<Arg type="java.lang.Integer">0</Arg>
|
||||
<Arg type="java.lang.String">/jndi/rmi://localhost:1099/jettyjmx</Arg>
|
||||
<Arg type="java.lang.Integer"><SystemProperty name="jetty.jmxrmiport" default="1099"/></Arg>
|
||||
<Arg type="java.lang.String">/jndi/rmi://<SystemProperty name="jetty.jmxrmihost" default="localhost"/>:<SystemProperty name="jetty.jmxrmiport" default="1099"/>/jmxrmi</Arg>
|
||||
</New>
|
||||
</Arg>
|
||||
<Arg>org.eclipse.jetty:name=rmiconnectorserver</Arg>
|
||||
<Arg>org.eclipse.jetty.jmx:name=rmiconnectorserver</Arg>
|
||||
<Call name="start" />
|
||||
</New>
|
||||
-->
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jndi</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jsp</artifactId>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-monitor</artifactId>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>jetty-nested</artifactId>
|
||||
<name>Jetty :: Nested</name>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-nosql</artifactId>
|
||||
|
|
|
@ -245,21 +245,37 @@ public class MongoSessionManager extends NoSqlSessionManager
|
|||
{
|
||||
for (String name : attrs.keySet())
|
||||
{
|
||||
if ( __METADATA.equals(name) )
|
||||
if (__METADATA.equals(name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
String attr = decodeName(name);
|
||||
Object value = decodeValue(attrs.get(name));
|
||||
session.doPutOrRemove(attr,value);
|
||||
session.bindValue(attr,value);
|
||||
|
||||
if (attrs.keySet().contains(name))
|
||||
{
|
||||
session.doPutOrRemove(attr,value);
|
||||
session.bindValue(attr,value);
|
||||
}
|
||||
else
|
||||
{
|
||||
session.doPutOrRemove(attr,value);
|
||||
}
|
||||
}
|
||||
// cleanup, remove values from session, that don't exist in data anymore:
|
||||
for (String name : session.getNames())
|
||||
{
|
||||
if (!attrs.keySet().contains(name))
|
||||
{
|
||||
session.doPutOrRemove(name,null);
|
||||
session.unbindValue(name,session.getAttribute(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
session.didActivate();
|
||||
|
||||
|
||||
|
||||
return version;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -348,7 +364,7 @@ public class MongoSessionManager extends NoSqlSessionManager
|
|||
BasicDBObject remove = new BasicDBObject();
|
||||
BasicDBObject unsets = new BasicDBObject();
|
||||
unsets.put(getContextKey(),1);
|
||||
remove.put("$unsets",unsets);
|
||||
remove.put("$unset",unsets);
|
||||
_sessions.update(key,remove);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-parent</artifactId>
|
||||
|
|
|
@ -31,7 +31,7 @@ Import-Package: com.sun.el;resolution:=optional,
|
|||
org.apache.jasper.tagplugins.jstl;version="6.0.0";resolution:=optional,
|
||||
org.apache.jasper.util;version="6.0.0";resolution:=optional,
|
||||
org.apache.jasper.xmlparser;version="6.0.0";resolution:=optional,
|
||||
org.glassfish.jasper.api;version="2.1.3";resolution:=optional,
|
||||
org.glassfish.jsp.api;version="2.1.3";resolution:=optional,
|
||||
org.apache.taglibs.standard;version="1.2.0";resolution:=optional,
|
||||
org.apache.taglibs.standard.extra.spath;version="1.2.0";resolution:=optional,
|
||||
org.apache.taglibs.standard.functions;version="1.2.0";resolution:=optional,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -39,7 +39,7 @@ import org.osgi.framework.BundleContext;
|
|||
public class DefaultJettyAtJettyHomeHelper {
|
||||
private static final Logger LOG = Log.getLogger(DefaultJettyAtJettyHomeHelper.class);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* contains a comma separated list of pathes to the etc/jetty-*.xml files
|
||||
* used to configure jetty. By default the value is 'etc/jetty.xml' when the
|
||||
|
@ -69,7 +69,7 @@ public class DefaultJettyAtJettyHomeHelper {
|
|||
* Usual system property used as the port for https for a typical jetty configuration.
|
||||
*/
|
||||
public static final String SYS_PROP_JETTY_PORT_SSL = "jetty.port.ssl";
|
||||
|
||||
|
||||
/**
|
||||
* Called by the JettyBootStrapActivator.
|
||||
* If the system property jetty.home is defined and points to a folder,
|
||||
|
@ -88,81 +88,76 @@ public class DefaultJettyAtJettyHomeHelper {
|
|||
* that might use them as part of their properties.
|
||||
* </p>
|
||||
*/
|
||||
public static void startJettyAtJettyHome(BundleContext bundleContext)
|
||||
public static void startJettyAtJettyHome(BundleContext bundleContext) throws Exception
|
||||
{
|
||||
String jettyHomeSysProp = System.getProperty(SYS_PROP_JETTY_HOME);
|
||||
String jettyHomeBundleSysProp = System.getProperty(SYS_PROP_JETTY_HOME_BUNDLE);
|
||||
File jettyHome = null;
|
||||
Bundle jettyHomeBundle = null;
|
||||
if (jettyHomeSysProp != null)
|
||||
{
|
||||
jettyHomeSysProp = resolvePropertyValue(jettyHomeSysProp);
|
||||
//bug 329621
|
||||
if (jettyHomeSysProp.startsWith("\"") && jettyHomeSysProp.endsWith("\"")
|
||||
|| (jettyHomeSysProp.startsWith("'") && jettyHomeSysProp.endsWith("'"))) {
|
||||
jettyHomeSysProp = jettyHomeSysProp.substring(1, jettyHomeSysProp.length() - 1);
|
||||
}
|
||||
if (jettyHomeBundleSysProp != null)
|
||||
{
|
||||
LOG.warn("Both the jetty.home property and the jetty.home.bundle property are defined."
|
||||
+ " jetty.home.bundle is not taken into account.");
|
||||
}
|
||||
jettyHome = new File(jettyHomeSysProp);
|
||||
if (!jettyHome.exists() || !jettyHome.isDirectory())
|
||||
{
|
||||
LOG.warn("Unable to locate the jetty.home folder " + jettyHomeSysProp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (jettyHomeBundleSysProp != null)
|
||||
{
|
||||
jettyHomeBundleSysProp = resolvePropertyValue(jettyHomeBundleSysProp);
|
||||
for (Bundle b : bundleContext.getBundles())
|
||||
{
|
||||
if (b.getSymbolicName().equals(jettyHomeBundleSysProp))
|
||||
{
|
||||
jettyHomeBundle = b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (jettyHomeBundle == null)
|
||||
{
|
||||
LOG.warn("Unable to find the jetty.home.bundle named " + jettyHomeSysProp);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
if (jettyHome == null && jettyHomeBundle == null)
|
||||
{
|
||||
LOG.warn("No default jetty started.");
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
Server server = new Server();
|
||||
Dictionary properties = new Hashtable();
|
||||
properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME);
|
||||
|
||||
String configURLs = jettyHome != null ? getJettyConfigurationURLs(jettyHome) : getJettyConfigurationURLs(jettyHomeBundle);
|
||||
properties.put(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS, configURLs);
|
||||
String jettyHomeSysProp = System.getProperty(SYS_PROP_JETTY_HOME);
|
||||
String jettyHomeBundleSysProp = System.getProperty(SYS_PROP_JETTY_HOME_BUNDLE);
|
||||
File jettyHome = null;
|
||||
Bundle jettyHomeBundle = null;
|
||||
if (jettyHomeSysProp != null)
|
||||
{
|
||||
jettyHomeSysProp = resolvePropertyValue(jettyHomeSysProp);
|
||||
//bug 329621
|
||||
if (jettyHomeSysProp.startsWith("\"") && jettyHomeSysProp.endsWith("\"")
|
||||
|| (jettyHomeSysProp.startsWith("'") && jettyHomeSysProp.endsWith("'"))) {
|
||||
jettyHomeSysProp = jettyHomeSysProp.substring(1, jettyHomeSysProp.length() - 1);
|
||||
}
|
||||
if (jettyHomeBundleSysProp != null)
|
||||
{
|
||||
LOG.warn("Both the jetty.home property and the jetty.home.bundle property are defined."
|
||||
+ " jetty.home.bundle is not taken into account.");
|
||||
}
|
||||
jettyHome = new File(jettyHomeSysProp);
|
||||
if (!jettyHome.exists() || !jettyHome.isDirectory())
|
||||
{
|
||||
LOG.warn("Unable to locate the jetty.home folder " + jettyHomeSysProp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (jettyHomeBundleSysProp != null)
|
||||
{
|
||||
jettyHomeBundleSysProp = resolvePropertyValue(jettyHomeBundleSysProp);
|
||||
for (Bundle b : bundleContext.getBundles())
|
||||
{
|
||||
if (b.getSymbolicName().equals(jettyHomeBundleSysProp))
|
||||
{
|
||||
jettyHomeBundle = b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (jettyHomeBundle == null)
|
||||
{
|
||||
LOG.warn("Unable to find the jetty.home.bundle named " + jettyHomeSysProp);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG.info("Configuring the default jetty server with " + configURLs);
|
||||
|
||||
//these properties usually are the ones passed to this type of configuration.
|
||||
setProperty(properties,SYS_PROP_JETTY_HOME,System.getProperty(SYS_PROP_JETTY_HOME));
|
||||
setProperty(properties,SYS_PROP_JETTY_HOST,System.getProperty(SYS_PROP_JETTY_HOST));
|
||||
setProperty(properties,SYS_PROP_JETTY_PORT,System.getProperty(SYS_PROP_JETTY_PORT));
|
||||
setProperty(properties,SYS_PROP_JETTY_PORT_SSL,System.getProperty(SYS_PROP_JETTY_PORT_SSL));
|
||||
}
|
||||
if (jettyHome == null && jettyHomeBundle == null)
|
||||
{
|
||||
LOG.warn("No default jetty started.");
|
||||
return;
|
||||
}
|
||||
|
||||
Server server = new Server();
|
||||
Dictionary properties = new Hashtable();
|
||||
properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME);
|
||||
|
||||
String configURLs = jettyHome != null ? getJettyConfigurationURLs(jettyHome) : getJettyConfigurationURLs(jettyHomeBundle);
|
||||
properties.put(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS, configURLs);
|
||||
|
||||
LOG.info("Configuring the default jetty server with " + configURLs);
|
||||
|
||||
//these properties usually are the ones passed to this type of configuration.
|
||||
setProperty(properties,SYS_PROP_JETTY_HOME,System.getProperty(SYS_PROP_JETTY_HOME));
|
||||
setProperty(properties,SYS_PROP_JETTY_HOST,System.getProperty(SYS_PROP_JETTY_HOST));
|
||||
setProperty(properties,SYS_PROP_JETTY_PORT,System.getProperty(SYS_PROP_JETTY_PORT));
|
||||
setProperty(properties,SYS_PROP_JETTY_PORT_SSL,System.getProperty(SYS_PROP_JETTY_PORT_SSL));
|
||||
|
||||
bundleContext.registerService(Server.class.getName(), server, properties);
|
||||
// hookNestedConnectorToBridgeServlet(server);
|
||||
|
||||
bundleContext.registerService(Server.class.getName(), server, properties);
|
||||
// hookNestedConnectorToBridgeServlet(server);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Minimum setup for the location of the configuration files given a jettyhome folder.
|
||||
* Reads the system property jetty.etc.config.urls and look for the corresponding jetty
|
||||
|
@ -172,22 +167,22 @@ public class DefaultJettyAtJettyHomeHelper {
|
|||
*/
|
||||
private static String getJettyConfigurationURLs(File jettyhome)
|
||||
{
|
||||
String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml");
|
||||
String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml");
|
||||
StringTokenizer tokenizer = new StringTokenizer(jettyetc,";,", false);
|
||||
StringBuilder res = new StringBuilder();
|
||||
while (tokenizer.hasMoreTokens())
|
||||
{
|
||||
String next = tokenizer.nextToken().trim();
|
||||
if (!next.startsWith("/") && next.indexOf(':') == -1)
|
||||
{
|
||||
try {
|
||||
next = new File(jettyhome, next).toURI().toURL().toString();
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
appendToCommaSeparatedList(res, next);
|
||||
String next = tokenizer.nextToken().trim();
|
||||
if (!next.startsWith("/") && next.indexOf(':') == -1)
|
||||
{
|
||||
try {
|
||||
next = new File(jettyhome, next).toURI().toURL().toString();
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
appendToCommaSeparatedList(res, next);
|
||||
}
|
||||
return res.toString();
|
||||
}
|
||||
|
@ -202,108 +197,108 @@ public class DefaultJettyAtJettyHomeHelper {
|
|||
*/
|
||||
private static String getJettyConfigurationURLs(Bundle configurationBundle)
|
||||
{
|
||||
String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml");
|
||||
String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml");
|
||||
StringTokenizer tokenizer = new StringTokenizer(jettyetc,";,", false);
|
||||
StringBuilder res = new StringBuilder();
|
||||
|
||||
|
||||
while (tokenizer.hasMoreTokens())
|
||||
{
|
||||
String etcFile = tokenizer.nextToken().trim();
|
||||
if (etcFile.startsWith("/") || etcFile.indexOf(":") != -1)
|
||||
{
|
||||
appendToCommaSeparatedList(res, etcFile);
|
||||
appendToCommaSeparatedList(res, etcFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
Enumeration<URL> enUrls = BundleFileLocatorHelper.DEFAULT
|
||||
.findEntries(configurationBundle, etcFile);
|
||||
|
||||
//default for org.eclipse.osgi.boot where we look inside jettyhome for the default embedded configuration.
|
||||
//default inside jettyhome. this way fragments to the bundle can define their own configuration.
|
||||
if ((enUrls == null || !enUrls.hasMoreElements()) && etcFile.endsWith("etc/jetty.xml"))
|
||||
{
|
||||
enUrls = BundleFileLocatorHelper.DEFAULT
|
||||
.findEntries(configurationBundle, "/jettyhome/etc/jetty-osgi-default.xml");
|
||||
System.err.println("Configuring jetty with the default embedded configuration:" +
|
||||
"bundle: " + configurationBundle.getSymbolicName() +
|
||||
" config: /jettyhome/etc/jetty-osgi-default.xml");
|
||||
}
|
||||
if (enUrls == null || !enUrls.hasMoreElements())
|
||||
{
|
||||
System.err.println("Unable to locate a jetty configuration file for " + etcFile);
|
||||
}
|
||||
if (enUrls != null)
|
||||
{
|
||||
while (enUrls.hasMoreElements())
|
||||
{
|
||||
appendToCommaSeparatedList(res, enUrls.nextElement().toString());
|
||||
}
|
||||
}
|
||||
Enumeration<URL> enUrls = BundleFileLocatorHelper.DEFAULT
|
||||
.findEntries(configurationBundle, etcFile);
|
||||
|
||||
//default for org.eclipse.osgi.boot where we look inside jettyhome for the default embedded configuration.
|
||||
//default inside jettyhome. this way fragments to the bundle can define their own configuration.
|
||||
if ((enUrls == null || !enUrls.hasMoreElements()) && etcFile.endsWith("etc/jetty.xml"))
|
||||
{
|
||||
enUrls = BundleFileLocatorHelper.DEFAULT
|
||||
.findEntries(configurationBundle, "/jettyhome/etc/jetty-osgi-default.xml");
|
||||
System.err.println("Configuring jetty with the default embedded configuration:" +
|
||||
"bundle: " + configurationBundle.getSymbolicName() +
|
||||
" config: /jettyhome/etc/jetty-osgi-default.xml");
|
||||
}
|
||||
if (enUrls == null || !enUrls.hasMoreElements())
|
||||
{
|
||||
System.err.println("Unable to locate a jetty configuration file for " + etcFile);
|
||||
}
|
||||
if (enUrls != null)
|
||||
{
|
||||
while (enUrls.hasMoreElements())
|
||||
{
|
||||
appendToCommaSeparatedList(res, enUrls.nextElement().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
private static void appendToCommaSeparatedList(StringBuilder buffer, String value)
|
||||
{
|
||||
if (buffer.length() != 0)
|
||||
{
|
||||
buffer.append(",");
|
||||
}
|
||||
buffer.append(value);
|
||||
}
|
||||
|
||||
private static void setProperty(Dictionary properties, String key, String value)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
properties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* recursively substitute the ${sysprop} by their actual system property.
|
||||
* ${sysprop,defaultvalue} will use 'defaultvalue' as the value if no sysprop is defined.
|
||||
* Not the most efficient code but we are shooting for simplicity and speed of development here.
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static String resolvePropertyValue(String value)
|
||||
{
|
||||
int ind = value.indexOf("${");
|
||||
if (ind == -1) {
|
||||
return value;
|
||||
}
|
||||
int ind2 = value.indexOf('}', ind);
|
||||
if (ind2 == -1) {
|
||||
return value;
|
||||
}
|
||||
String sysprop = value.substring(ind+2, ind2);
|
||||
String defaultValue = null;
|
||||
int comma = sysprop.indexOf(',');
|
||||
if (comma != -1 && comma+1 != sysprop.length())
|
||||
{
|
||||
defaultValue = sysprop.substring(comma+1);
|
||||
defaultValue = resolvePropertyValue(defaultValue);
|
||||
sysprop = sysprop.substring(0,comma);
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultValue = "${" + sysprop + "}";
|
||||
}
|
||||
|
||||
String v = System.getProperty(sysprop);
|
||||
|
||||
String reminder = value.length() > ind2 + 1 ? value.substring(ind2+1) : "";
|
||||
reminder = resolvePropertyValue(reminder);
|
||||
if (v != null)
|
||||
{
|
||||
return value.substring(0, ind) + v + reminder;
|
||||
}
|
||||
else
|
||||
{
|
||||
return value.substring(0, ind) + defaultValue + reminder;
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendToCommaSeparatedList(StringBuilder buffer, String value)
|
||||
{
|
||||
if (buffer.length() != 0)
|
||||
{
|
||||
buffer.append(",");
|
||||
}
|
||||
buffer.append(value);
|
||||
}
|
||||
|
||||
private static void setProperty(Dictionary properties, String key, String value)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
properties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* recursively substitute the ${sysprop} by their actual system property.
|
||||
* ${sysprop,defaultvalue} will use 'defaultvalue' as the value if no sysprop is defined.
|
||||
* Not the most efficient code but we are shooting for simplicity and speed of development here.
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static String resolvePropertyValue(String value)
|
||||
{
|
||||
int ind = value.indexOf("${");
|
||||
if (ind == -1) {
|
||||
return value;
|
||||
}
|
||||
int ind2 = value.indexOf('}', ind);
|
||||
if (ind2 == -1) {
|
||||
return value;
|
||||
}
|
||||
String sysprop = value.substring(ind+2, ind2);
|
||||
String defaultValue = null;
|
||||
int comma = sysprop.indexOf(',');
|
||||
if (comma != -1 && comma+1 != sysprop.length())
|
||||
{
|
||||
defaultValue = sysprop.substring(comma+1);
|
||||
defaultValue = resolvePropertyValue(defaultValue);
|
||||
sysprop = sysprop.substring(0,comma);
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultValue = "${" + sysprop + "}";
|
||||
}
|
||||
|
||||
String v = System.getProperty(sysprop);
|
||||
|
||||
String reminder = value.length() > ind2 + 1 ? value.substring(ind2+1) : "";
|
||||
reminder = resolvePropertyValue(reminder);
|
||||
if (v != null)
|
||||
{
|
||||
return value.substring(0, ind) + v + reminder;
|
||||
}
|
||||
else
|
||||
{
|
||||
return value.substring(0, ind) + defaultValue + reminder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,50 +18,53 @@ import java.util.Properties;
|
|||
|
||||
import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.ServiceEvent;
|
||||
import org.osgi.framework.ServiceListener;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
|
||||
/**
|
||||
* Deploy the jetty server instances when they are registered as an OSGi service.
|
||||
* Deploy the jetty server instances when they are registered as an OSGi
|
||||
* service.
|
||||
*/
|
||||
public class JettyServerServiceTracker implements ServiceListener, IManagedJettyServerRegistry
|
||||
{
|
||||
|
||||
private static Logger LOG = Log.getLogger(JettyServerServiceTracker.class.getName());
|
||||
|
||||
/**
|
||||
* Servers indexed by PIDs. PIDs are generated by the ConfigurationAdmin service.
|
||||
* Servers indexed by PIDs. PIDs are generated by the ConfigurationAdmin
|
||||
* service.
|
||||
*/
|
||||
private Map<String, ServerInstanceWrapper> _serversIndexedByName = new HashMap<String, ServerInstanceWrapper>();
|
||||
|
||||
/** The context-handler to deactivate indexed by ServerInstanceWrapper */
|
||||
private Map<ServiceReference, ServerInstanceWrapper> _indexByServiceReference = new HashMap<ServiceReference, ServerInstanceWrapper>();
|
||||
|
||||
|
||||
/**
|
||||
* Stops each one of the registered servers.
|
||||
*/
|
||||
public void stop()
|
||||
{
|
||||
//not sure that this is really useful but here we go.
|
||||
for (ServerInstanceWrapper wrapper : _serversIndexedByName.values())
|
||||
{
|
||||
try
|
||||
{
|
||||
wrapper.stop();
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
// not sure that this is really useful but here we go.
|
||||
for (ServerInstanceWrapper wrapper : _serversIndexedByName.values())
|
||||
{
|
||||
try
|
||||
{
|
||||
wrapper.stop();
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
LOG.warn(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Receives notification that a service has had a lifecycle change.
|
||||
*
|
||||
* @param ev
|
||||
* The <code>ServiceEvent</code> object.
|
||||
* @param ev The <code>ServiceEvent</code> object.
|
||||
*/
|
||||
public void serviceChanged(ServiceEvent ev)
|
||||
{
|
||||
|
@ -71,17 +74,16 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty
|
|||
case ServiceEvent.MODIFIED:
|
||||
case ServiceEvent.UNREGISTERING:
|
||||
{
|
||||
ServerInstanceWrapper instance = unregisterInIndex(ev.getServiceReference());
|
||||
ServerInstanceWrapper instance = unregisterInIndex(ev.getServiceReference());
|
||||
if (instance != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
instance.stop();
|
||||
instance.stop();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,32 +98,35 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty
|
|||
}
|
||||
case ServiceEvent.REGISTERED:
|
||||
{
|
||||
Bundle contributor = sr.getBundle();
|
||||
Server server = (Server)contributor.getBundleContext().getService(sr);
|
||||
ServerInstanceWrapper wrapper = registerInIndex(server, sr);
|
||||
Properties props = new Properties();
|
||||
for (String key : sr.getPropertyKeys())
|
||||
{
|
||||
Object value = sr.getProperty(key);
|
||||
props.put(key, value);
|
||||
}
|
||||
wrapper.start(server, props);
|
||||
break;
|
||||
try
|
||||
{
|
||||
Bundle contributor = sr.getBundle();
|
||||
Server server = (Server) contributor.getBundleContext().getService(sr);
|
||||
ServerInstanceWrapper wrapper = registerInIndex(server, sr);
|
||||
Properties props = new Properties();
|
||||
for (String key : sr.getPropertyKeys())
|
||||
{
|
||||
Object value = sr.getProperty(key);
|
||||
props.put(key, value);
|
||||
}
|
||||
wrapper.start(server, props);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ServerInstanceWrapper registerInIndex(Server server, ServiceReference sr)
|
||||
{
|
||||
String name = (String)sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
if (name == null)
|
||||
{
|
||||
throw new IllegalArgumentException("The property " +
|
||||
OSGiServerConstants.MANAGED_JETTY_SERVER_NAME + " is mandatory");
|
||||
}
|
||||
String name = (String) sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
if (name == null) { throw new IllegalArgumentException("The property " + OSGiServerConstants.MANAGED_JETTY_SERVER_NAME + " is mandatory"); }
|
||||
ServerInstanceWrapper wrapper = new ServerInstanceWrapper(name);
|
||||
_indexByServiceReference.put(sr,wrapper);
|
||||
_serversIndexedByName.put(name,wrapper);
|
||||
_indexByServiceReference.put(sr, wrapper);
|
||||
_serversIndexedByName.put(name, wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
|
@ -133,7 +138,7 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty
|
|||
*/
|
||||
private ServerInstanceWrapper unregisterInIndex(ServiceReference sr)
|
||||
{
|
||||
ServerInstanceWrapper handler = _indexByServiceReference.remove(sr);
|
||||
ServerInstanceWrapper handler = _indexByServiceReference.remove(sr);
|
||||
if (handler == null)
|
||||
{
|
||||
// a warning?
|
||||
|
@ -149,13 +154,12 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty
|
|||
|
||||
/**
|
||||
* @param managedServerName The server name
|
||||
* @return the corresponding jetty server wrapped with its deployment properties.
|
||||
* @return the corresponding jetty server wrapped with its deployment
|
||||
* properties.
|
||||
*/
|
||||
public ServerInstanceWrapper getServerInstanceWrapper(String managedServerName)
|
||||
{
|
||||
return _serversIndexedByName.get(managedServerName == null
|
||||
? OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME : managedServerName);
|
||||
return _serversIndexedByName.get(managedServerName == null ? OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME : managedServerName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -99,14 +99,21 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag
|
|||
String name = (String)properties.get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
if (name == null)
|
||||
{
|
||||
throw new ConfigurationException(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME,
|
||||
"The name of the server is mandatory");
|
||||
throw new ConfigurationException(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME,
|
||||
"The name of the server is mandatory");
|
||||
}
|
||||
serverInstanceWrapper = new ServerInstanceWrapper(name);
|
||||
_serversIndexedByPID.put(pid, serverInstanceWrapper);
|
||||
_serversNameIndexedByPID.put(pid, name);
|
||||
_serversPIDIndexedByName.put(name, pid);
|
||||
serverInstanceWrapper.start(new Server(), properties);
|
||||
try
|
||||
{
|
||||
serverInstanceWrapper.start(new Server(), properties);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ConfigurationException(null, "Error starting jetty server instance", e);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void deleted(String pid)
|
||||
|
|
|
@ -44,28 +44,29 @@ import org.eclipse.jetty.util.resource.Resource;
|
|||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
|
||||
/**
|
||||
* Exposes a Jetty Server to be managed by an OSGi ManagedServiceFactory
|
||||
* Configure and start it.
|
||||
* Can also be used from the ManagedServiceFactory
|
||||
* Configure and start it. Can also be used from the ManagedServiceFactory
|
||||
*/
|
||||
public class ServerInstanceWrapper {
|
||||
public class ServerInstanceWrapper
|
||||
{
|
||||
|
||||
/** The value of this property points to the parent director of
|
||||
* the jetty.xml configuration file currently executed.
|
||||
* Everything is passed as a URL to support the
|
||||
* case where the bundle is zipped. */
|
||||
/**
|
||||
* The value of this property points to the parent director of the jetty.xml
|
||||
* configuration file currently executed. Everything is passed as a URL to
|
||||
* support the case where the bundle is zipped.
|
||||
*/
|
||||
public static final String PROPERTY_THIS_JETTY_XML_FOLDER_URL = "this.jetty.xml.parent.folder.url";
|
||||
|
||||
private static Logger __logger = Log.getLogger(ServerInstanceWrapper.class.getName());
|
||||
|
||||
private static Logger LOG = Log.getLogger(ServerInstanceWrapper.class.getName());
|
||||
|
||||
private final String _managedServerName;
|
||||
|
||||
|
||||
/**
|
||||
* The managed jetty server
|
||||
*/
|
||||
private Server _server;
|
||||
|
||||
private ContextHandlerCollection _ctxtHandler;
|
||||
|
||||
/**
|
||||
|
@ -74,32 +75,34 @@ public class ServerInstanceWrapper {
|
|||
* let the TldScanner find the jars where the tld files are.
|
||||
*/
|
||||
private ClassLoader _commonParentClassLoaderForWebapps;
|
||||
|
||||
private DeploymentManager _deploymentManager;
|
||||
|
||||
private OSGiAppProvider _provider;
|
||||
|
||||
|
||||
private WebBundleDeployerHelper _webBundleDeployerHelper;
|
||||
|
||||
|
||||
|
||||
public ServerInstanceWrapper(String managedServerName)
|
||||
{
|
||||
_managedServerName = managedServerName;
|
||||
}
|
||||
|
||||
|
||||
public String getManagedServerName()
|
||||
{
|
||||
return _managedServerName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The classloader that should be the parent classloader for
|
||||
* each webapp deployed on this server.
|
||||
* The classloader that should be the parent classloader for each webapp
|
||||
* deployed on this server.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public ClassLoader getParentClassLoaderForWebapps()
|
||||
{
|
||||
return _commonParentClassLoaderForWebapps;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return The deployment manager registered on this server.
|
||||
*/
|
||||
|
@ -107,7 +110,7 @@ public class ServerInstanceWrapper {
|
|||
{
|
||||
return _deploymentManager;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return The app provider registered on this server.
|
||||
*/
|
||||
|
@ -115,19 +118,17 @@ public class ServerInstanceWrapper {
|
|||
{
|
||||
return _provider;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Server getServer()
|
||||
{
|
||||
return _server;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public WebBundleDeployerHelper getWebBundleDeployerHelp()
|
||||
{
|
||||
return _webBundleDeployerHelper;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return The collection of context handlers
|
||||
*/
|
||||
|
@ -136,8 +137,7 @@ public class ServerInstanceWrapper {
|
|||
return _ctxtHandler;
|
||||
}
|
||||
|
||||
|
||||
public void start(Server server, Dictionary props)
|
||||
public void start(Server server, Dictionary props) throws Exception
|
||||
{
|
||||
_server = server;
|
||||
ClassLoader contextCl = Thread.currentThread().getContextClassLoader();
|
||||
|
@ -146,62 +146,61 @@ public class ServerInstanceWrapper {
|
|||
// passing this bundle's classloader as the context classlaoder
|
||||
// makes sure there is access to all the jetty's bundles
|
||||
ClassLoader libExtClassLoader = null;
|
||||
String sharedURLs = (String)props.get(OSGiServerConstants.MANAGED_JETTY_SHARED_LIB_FOLDER_URLS);
|
||||
try
|
||||
{
|
||||
List<File> shared = sharedURLs != null ? extractFiles(sharedURLs) : null;
|
||||
libExtClassLoader = LibExtClassLoaderHelper.createLibExtClassLoader(
|
||||
shared, null, server, JettyBootstrapActivator.class.getClassLoader());
|
||||
}
|
||||
catch (MalformedURLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
String sharedURLs = (String) props.get(OSGiServerConstants.MANAGED_JETTY_SHARED_LIB_FOLDER_URLS);
|
||||
|
||||
List<File> shared = sharedURLs != null ? extractFiles(sharedURLs) : null;
|
||||
libExtClassLoader = LibExtClassLoaderHelper.createLibExtClassLoader(shared, null, server, JettyBootstrapActivator.class.getClassLoader());
|
||||
|
||||
Thread.currentThread().setContextClassLoader(libExtClassLoader);
|
||||
|
||||
|
||||
configure(server, props);
|
||||
|
||||
init();
|
||||
|
||||
//now that we have an app provider we can call the registration customizer.
|
||||
try
|
||||
{
|
||||
URL[] jarsWithTlds = getJarsWithTlds();
|
||||
_commonParentClassLoaderForWebapps = jarsWithTlds == null
|
||||
? libExtClassLoader
|
||||
:new TldLocatableURLClassloader(libExtClassLoader,jarsWithTlds);
|
||||
}
|
||||
catch (MalformedURLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
// now that we have an app provider we can call the registration
|
||||
// customizer.
|
||||
|
||||
URL[] jarsWithTlds = getJarsWithTlds();
|
||||
_commonParentClassLoaderForWebapps = jarsWithTlds == null ? libExtClassLoader : new TldLocatableURLClassloader(libExtClassLoader, jarsWithTlds);
|
||||
|
||||
|
||||
server.start();
|
||||
_webBundleDeployerHelper = new WebBundleDeployerHelper(this);
|
||||
}
|
||||
catch (Throwable t)
|
||||
catch (Exception e)
|
||||
{
|
||||
t.printStackTrace();
|
||||
if (server != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
LOG.ignore(x);
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(contextCl);
|
||||
}
|
||||
_webBundleDeployerHelper = new WebBundleDeployerHelper(this);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void stop()
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
if (_server.isRunning())
|
||||
{
|
||||
_server.stop();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,14 +228,13 @@ public class ServerInstanceWrapper {
|
|||
private URL[] getJarsWithTlds() throws Exception
|
||||
{
|
||||
ArrayList<URL> res = new ArrayList<URL>();
|
||||
WebBundleDeployerHelper.staticInit();//that is not looking great.
|
||||
WebBundleDeployerHelper.staticInit();// that is not looking great.
|
||||
for (WebappRegistrationCustomizer regCustomizer : WebBundleDeployerHelper.JSP_REGISTRATION_HELPERS)
|
||||
{
|
||||
URL[] urls = regCustomizer.getJarsWithTlds(_provider, WebBundleDeployerHelper.BUNDLE_FILE_LOCATOR_HELPER);
|
||||
for (URL url : urls)
|
||||
{
|
||||
if (!res.contains(url))
|
||||
res.add(url);
|
||||
if (!res.contains(url)) res.add(url);
|
||||
}
|
||||
}
|
||||
if (!res.isEmpty())
|
||||
|
@ -244,19 +242,15 @@ public class ServerInstanceWrapper {
|
|||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private void configure(Server server, Dictionary props) throws Exception
|
||||
{
|
||||
String jettyConfigurationUrls = (String) props.get(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS);
|
||||
List<URL> jettyConfigurations = jettyConfigurationUrls != null
|
||||
? extractResources(jettyConfigurationUrls) : null;
|
||||
if (jettyConfigurations == null || jettyConfigurations.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Map<String,Object> id_map = new HashMap<String,Object>();
|
||||
id_map.put("Server",server);
|
||||
Map<String,String> properties = new HashMap<String,String>();
|
||||
List<URL> jettyConfigurations = jettyConfigurationUrls != null ? extractResources(jettyConfigurationUrls) : null;
|
||||
if (jettyConfigurations == null || jettyConfigurations.isEmpty()) { return; }
|
||||
Map<String, Object> id_map = new HashMap<String, Object>();
|
||||
id_map.put("Server", server);
|
||||
Map<String, String> properties = new HashMap<String, String>();
|
||||
Enumeration<Object> en = props.keys();
|
||||
while (en.hasMoreElements())
|
||||
{
|
||||
|
@ -275,15 +269,17 @@ public class ServerInstanceWrapper {
|
|||
is = r.getInputStream();
|
||||
XmlConfiguration config = new XmlConfiguration(is);
|
||||
config.getIdMap().putAll(id_map);
|
||||
|
||||
//#334062 compute the URL of the folder that contains the jetty.xml conf file
|
||||
//and set it as a property so we can compute relative paths from it.
|
||||
|
||||
// #334062 compute the URL of the folder that contains the
|
||||
// jetty.xml conf file
|
||||
// and set it as a property so we can compute relative paths
|
||||
// from it.
|
||||
String urlPath = jettyConfiguration.toString();
|
||||
int lastSlash = urlPath.lastIndexOf('/');
|
||||
if (lastSlash > 4)
|
||||
{
|
||||
urlPath = urlPath.substring(0, lastSlash);
|
||||
Map<String,String> properties2 = new HashMap<String,String>(properties);
|
||||
Map<String, String> properties2 = new HashMap<String, String>(properties);
|
||||
properties2.put(PROPERTY_THIS_JETTY_XML_FOLDER_URL, urlPath);
|
||||
config.getProperties().putAll(properties2);
|
||||
}
|
||||
|
@ -292,11 +288,11 @@ public class ServerInstanceWrapper {
|
|||
config.getProperties().putAll(properties);
|
||||
}
|
||||
config.configure();
|
||||
id_map=config.getIdMap();
|
||||
id_map = config.getIdMap();
|
||||
}
|
||||
catch (SAXParseException saxparse)
|
||||
{
|
||||
__logger.warn("Unable to configure the jetty/etc file " + jettyConfiguration,saxparse);
|
||||
LOG.warn("Unable to configure the jetty/etc file " + jettyConfiguration, saxparse);
|
||||
throw saxparse;
|
||||
}
|
||||
finally
|
||||
|
@ -306,8 +302,7 @@ public class ServerInstanceWrapper {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Must be called after the server is configured.
|
||||
*
|
||||
|
@ -319,50 +314,48 @@ public class ServerInstanceWrapper {
|
|||
private void init()
|
||||
{
|
||||
// Get the context handler
|
||||
_ctxtHandler = (ContextHandlerCollection)_server.getChildHandlerByClass(ContextHandlerCollection.class);
|
||||
|
||||
_ctxtHandler = (ContextHandlerCollection) _server.getChildHandlerByClass(ContextHandlerCollection.class);
|
||||
|
||||
// get a deployerManager
|
||||
List<DeploymentManager> deployers = _server.getBeans(DeploymentManager.class);
|
||||
if (deployers != null && !deployers.isEmpty())
|
||||
{
|
||||
_deploymentManager = deployers.get(0);
|
||||
|
||||
|
||||
for (AppProvider provider : _deploymentManager.getAppProviders())
|
||||
{
|
||||
if (provider instanceof OSGiAppProvider)
|
||||
{
|
||||
_provider=(OSGiAppProvider)provider;
|
||||
_provider = (OSGiAppProvider) provider;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_provider == null)
|
||||
{
|
||||
//create it on the fly with reasonable default values.
|
||||
// create it on the fly with reasonable default values.
|
||||
try
|
||||
{
|
||||
_provider = new OSGiAppProvider();
|
||||
_provider.setMonitoredDirResource(
|
||||
Resource.newResource(getDefaultOSGiContextsHome(
|
||||
new File(System.getProperty("jetty.home"))).toURI()));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
_provider.setMonitoredDirResource(Resource.newResource(getDefaultOSGiContextsHome(new File(System.getProperty("jetty.home"))).toURI()));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
_deploymentManager.addAppProvider(_provider);
|
||||
}
|
||||
}
|
||||
|
||||
if (_ctxtHandler == null || _provider==null)
|
||||
throw new IllegalStateException("ERROR: No ContextHandlerCollection or OSGiAppProvider configured");
|
||||
|
||||
if (_ctxtHandler == null || _provider == null) throw new IllegalStateException("ERROR: No ContextHandlerCollection or OSGiAppProvider configured");
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return The default folder in which the context files of the osgi bundles
|
||||
* are located and watched. Or null when the system property
|
||||
* "jetty.osgi.contexts.home" is not defined.
|
||||
* If the configuration file defines the OSGiAppProvider's context.
|
||||
* This will not be taken into account.
|
||||
* "jetty.osgi.contexts.home" is not defined. If the configuration
|
||||
* file defines the OSGiAppProvider's context. This will not be
|
||||
* taken into account.
|
||||
*/
|
||||
File getDefaultOSGiContextsHome(File jettyHome)
|
||||
{
|
||||
|
@ -370,20 +363,19 @@ public class ServerInstanceWrapper {
|
|||
if (jettyContextsHome != null)
|
||||
{
|
||||
File contextsHome = new File(jettyContextsHome);
|
||||
if (!contextsHome.exists() || !contextsHome.isDirectory())
|
||||
{
|
||||
throw new IllegalArgumentException("the ${jetty.osgi.contexts.home} '" + jettyContextsHome + " must exist and be a folder");
|
||||
}
|
||||
if (!contextsHome.exists() || !contextsHome.isDirectory()) { throw new IllegalArgumentException(
|
||||
"the ${jetty.osgi.contexts.home} '" + jettyContextsHome
|
||||
+ " must exist and be a folder"); }
|
||||
return contextsHome;
|
||||
}
|
||||
return new File(jettyHome, "/contexts");
|
||||
}
|
||||
|
||||
|
||||
File getOSGiContextsHome()
|
||||
{
|
||||
return _provider.getContextXmlDirAsFile();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the urls in this string.
|
||||
*/
|
||||
|
@ -396,19 +388,19 @@ public class ServerInstanceWrapper {
|
|||
String tok = tokenizer.nextToken();
|
||||
try
|
||||
{
|
||||
urls.add(((DefaultFileLocatorHelper) WebBundleDeployerHelper
|
||||
.BUNDLE_FILE_LOCATOR_HELPER).getLocalURL(new URL(tok)));
|
||||
urls.add(((DefaultFileLocatorHelper) WebBundleDeployerHelper.BUNDLE_FILE_LOCATOR_HELPER).getLocalURL(new URL(tok)));
|
||||
}
|
||||
catch (Throwable mfe)
|
||||
{
|
||||
|
||||
LOG.warn(mfe);
|
||||
}
|
||||
}
|
||||
return urls;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the folders that might contain jars for the legacy J2EE shared libraries
|
||||
* Get the folders that might contain jars for the legacy J2EE shared
|
||||
* libraries
|
||||
*/
|
||||
private List<File> extractFiles(String propertyValue)
|
||||
{
|
||||
|
@ -420,8 +412,7 @@ public class ServerInstanceWrapper {
|
|||
try
|
||||
{
|
||||
URL url = new URL(tok);
|
||||
url = ((DefaultFileLocatorHelper) WebBundleDeployerHelper
|
||||
.BUNDLE_FILE_LOCATOR_HELPER).getFileURL(url);
|
||||
url = ((DefaultFileLocatorHelper) WebBundleDeployerHelper.BUNDLE_FILE_LOCATOR_HELPER).getFileURL(url);
|
||||
if (url.getProtocol().equals("file"))
|
||||
{
|
||||
Resource res = Resource.newResource(url);
|
||||
|
@ -434,11 +425,10 @@ public class ServerInstanceWrapper {
|
|||
}
|
||||
catch (Throwable mfe)
|
||||
{
|
||||
|
||||
LOG.warn(mfe);
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-overlay-deployer</artifactId>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-plus</artifactId>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>jetty-policy</artifactId>
|
||||
<name>Jetty :: Policy Tool</name>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-rewrite</artifactId>
|
||||
|
|
|
@ -24,12 +24,15 @@ import org.eclipse.jetty.server.Request;
|
|||
* Rewrite the URI by matching with a regular expression.
|
||||
* The replacement string may use $n" to replace the nth capture group.
|
||||
* If the replacement string contains ? character, then it is split into a path
|
||||
* and query string component. The returned target contains only the path.
|
||||
* and query string component. The replacement query string may also contain $Q, which
|
||||
* is replaced with the original query string.
|
||||
* The returned target contains only the path.
|
||||
*/
|
||||
public class RewriteRegexRule extends RegexRule implements Rule.ApplyURI
|
||||
{
|
||||
private String _replacement;
|
||||
private String _query;
|
||||
private boolean _queryGroup;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public RewriteRegexRule()
|
||||
|
@ -49,6 +52,7 @@ public class RewriteRegexRule extends RegexRule implements Rule.ApplyURI
|
|||
String[] split=replacement.split("\\?",2);
|
||||
_replacement = split[0];
|
||||
_query=split.length==2?split[1]:null;
|
||||
_queryGroup=_query!=null && _query.contains("$Q");
|
||||
}
|
||||
|
||||
|
||||
|
@ -73,7 +77,12 @@ public class RewriteRegexRule extends RegexRule implements Rule.ApplyURI
|
|||
}
|
||||
|
||||
if (query!=null)
|
||||
{
|
||||
if (_queryGroup)
|
||||
query=query.replace("$Q",request.getQueryString()==null?"":request.getQueryString());
|
||||
request.setAttribute("org.eclipse.jetty.rewrite.handler.RewriteRegexRule.Q",query);
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
|
@ -84,7 +93,7 @@ public class RewriteRegexRule extends RegexRule implements Rule.ApplyURI
|
|||
if (_query!=null)
|
||||
{
|
||||
String query=(String)request.getAttribute("org.eclipse.jetty.rewrite.handler.RewriteRegexRule.Q");
|
||||
if (request.getQueryString()==null)
|
||||
if (_queryGroup||request.getQueryString()==null)
|
||||
request.setQueryString(query);
|
||||
else
|
||||
request.setQueryString(request.getQueryString()+"&"+query);
|
||||
|
|
|
@ -197,28 +197,25 @@ public class RuleContainer extends Rule
|
|||
if (applied!=null)
|
||||
{
|
||||
LOG.debug("applied {}",rule);
|
||||
if (!target.equals(applied))
|
||||
{
|
||||
LOG.debug("rewrote {} to {}",target,applied);
|
||||
if (!original_set)
|
||||
{
|
||||
original_set=true;
|
||||
request.setAttribute(_originalPathAttribute, target);
|
||||
}
|
||||
LOG.debug("rewrote {} to {}",target,applied);
|
||||
if (!original_set)
|
||||
{
|
||||
original_set=true;
|
||||
request.setAttribute(_originalPathAttribute, target);
|
||||
}
|
||||
|
||||
if (_rewriteRequestURI)
|
||||
{
|
||||
if (rule instanceof Rule.ApplyURI && !target.equals(request.getRequestURI()))
|
||||
((Rule.ApplyURI)rule).applyURI((Request)request, target, applied);
|
||||
else
|
||||
((Request)request).setRequestURI(applied);
|
||||
}
|
||||
|
||||
if (_rewritePathInfo)
|
||||
((Request)request).setPathInfo(applied);
|
||||
|
||||
target=applied;
|
||||
if (_rewriteRequestURI)
|
||||
{
|
||||
if (rule instanceof Rule.ApplyURI)
|
||||
((Rule.ApplyURI)rule).applyURI((Request)request, target, applied);
|
||||
else
|
||||
((Request)request).setRequestURI(applied);
|
||||
}
|
||||
|
||||
if (_rewritePathInfo)
|
||||
((Request)request).setPathInfo(applied);
|
||||
|
||||
target=applied;
|
||||
|
||||
if (rule.isHandling())
|
||||
{
|
||||
|
|
|
@ -23,13 +23,21 @@ public class RewriteRegexRuleTest extends AbstractRuleTestCase
|
|||
{
|
||||
private String[][] _tests=
|
||||
{
|
||||
{"/foo/bar",".*","/replace","/replace",null},
|
||||
{"/foo/bar","/xxx.*","/replace",null,null},
|
||||
{"/foo/bar","/(.*)/(.*)","/$2/$1/xxx","/bar/foo/xxx",null},
|
||||
{"/foo/bar","/(foo)/(.*)(bar)","/$3/$1/xxx$2","/bar/foo/xxx",null},
|
||||
{"/foo/$bar",".*","/$replace","/$replace",null},
|
||||
{"/foo/$bar","/foo/(.*)","/$1/replace","/$bar/replace",null},
|
||||
{"/foo/bar/info","/foo/(NotHere)?([^/]*)/(.*)","/$3/other?p1=$2","/info/other","p1=bar"},
|
||||
{"/foo/bar",null,".*","/replace","/replace",null},
|
||||
{"/foo/bar","n=v",".*","/replace","/replace","n=v"},
|
||||
{"/foo/bar",null,"/xxx.*","/replace",null,null},
|
||||
{"/foo/bar",null,"/(.*)/(.*)","/$2/$1/xxx","/bar/foo/xxx",null},
|
||||
{"/foo/bar",null,"/(.*)/(.*)","/test?p2=$2&p1=$1","/test","p2=bar&p1=foo"},
|
||||
{"/foo/bar","n=v","/(.*)/(.*)","/test?p2=$2&p1=$1","/test","n=v&p2=bar&p1=foo"},
|
||||
{"/foo/bar",null,"/(.*)/(.*)","/foo/bar?p2=$2&p1=$1","/foo/bar","p2=bar&p1=foo"},
|
||||
{"/foo/bar","n=v","/(.*)/(.*)","/foo/bar?p2=$2&p1=$1","/foo/bar","n=v&p2=bar&p1=foo"},
|
||||
{"/foo/bar",null,"/(foo)/(.*)(bar)","/$3/$1/xxx$2","/bar/foo/xxx",null},
|
||||
{"/foo/$bar",null,".*","/$replace","/$replace",null},
|
||||
{"/foo/$bar",null,"/foo/(.*)","/$1/replace","/$bar/replace",null},
|
||||
{"/foo/bar/info",null,"/foo/(NotHere)?([^/]*)/(.*)","/$3/other?p1=$2","/info/other","p1=bar"},
|
||||
{"/foo/bar/info",null,"/foo/(NotHere)?([^/]*)/(.*)","/$3/other?p1=$2&$Q","/info/other","p1=bar&"},
|
||||
{"/foo/bar/info","n=v","/foo/(NotHere)?([^/]*)/(.*)","/$3/other?p1=$2&$Q","/info/other","p1=bar&n=v"},
|
||||
{"/foo/bar/info","n=v","/foo/(NotHere)?([^/]*)/(.*)","/$3/other?p1=$2","/info/other","n=v&p1=bar"},
|
||||
};
|
||||
private RewriteRegexRule _rule;
|
||||
|
||||
|
@ -45,17 +53,43 @@ public class RewriteRegexRuleTest extends AbstractRuleTestCase
|
|||
{
|
||||
for (String[] test : _tests)
|
||||
{
|
||||
_rule.setRegex(test[1]);
|
||||
_rule.setReplacement(test[2]);
|
||||
String result = _rule.matchAndApply(test[0], _request, _response);
|
||||
assertEquals(test[1], test[3], result);
|
||||
|
||||
String t=test[0]+"?"+test[1]+">"+test[2]+"|"+test[3];
|
||||
_rule.setRegex(test[2]);
|
||||
_rule.setReplacement(test[3]);
|
||||
|
||||
_request.setRequestURI(test[0]);
|
||||
_request.setQueryString(null);
|
||||
_request.setQueryString(test[1]);
|
||||
_request.getAttributes().clearAttributes();
|
||||
|
||||
String result = _rule.matchAndApply(test[0], _request, _response);
|
||||
assertEquals(t, test[4], result);
|
||||
_rule.applyURI(_request,test[0],result);
|
||||
|
||||
assertEquals(test[3], _request.getRequestURI());
|
||||
assertEquals(test[4], _request.getQueryString());
|
||||
assertEquals(t,test[4], _request.getRequestURI());
|
||||
assertEquals(t,test[5], _request.getQueryString());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContainedRequestUriEnabled() throws IOException
|
||||
{
|
||||
RuleContainer container = new RuleContainer();
|
||||
container.setRewriteRequestURI(true);
|
||||
container.addRule(_rule);
|
||||
for (String[] test : _tests)
|
||||
{
|
||||
String t=test[0]+"?"+test[1]+">"+test[2]+"|"+test[3];
|
||||
_rule.setRegex(test[2]);
|
||||
_rule.setReplacement(test[3]);
|
||||
|
||||
_request.setRequestURI(test[0]);
|
||||
_request.setQueryString(test[1]);
|
||||
_request.getAttributes().clearAttributes();
|
||||
|
||||
String result = container.apply(test[0],_request,_response);
|
||||
assertEquals(t,test[4]==null?test[0]:test[4], result);
|
||||
assertEquals(t,test[4]==null?test[0]:test[4], _request.getRequestURI());
|
||||
assertEquals(t,test[5], _request.getQueryString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-security</artifactId>
|
||||
|
|
|
@ -12,7 +12,7 @@ The easiest place to put these lines are in the start.ini file.
|
|||
For debugging the spengo authentication the following options are helpful:
|
||||
|
||||
-Dorg.eclipse.jetty.LEVEL=debug
|
||||
-Dsun.security.spnego.debug=all
|
||||
-Dsun.security.spnego.debug=true
|
||||
|
||||
|
||||
Spengo Authentication is enabled in the webapp with the following setup.
|
||||
|
@ -59,7 +59,4 @@ embedded, via the jetty.xml or in a context file for the webapp.
|
|||
</New>
|
||||
</Set>
|
||||
<Set name="checkWelcomeFiles">true</Set>
|
||||
</Get>
|
||||
|
||||
|
||||
8
|
||||
</Get>
|
|
@ -254,7 +254,7 @@ public class DigestAuthenticator extends LoginAuthenticator
|
|||
Nonce nonce=_nonceQueue.peek();
|
||||
while (nonce!=null && nonce._ts<expired)
|
||||
{
|
||||
_nonceQueue.remove();
|
||||
_nonceQueue.remove(nonce);
|
||||
_nonceCount.remove(nonce._nonce);
|
||||
nonce=_nonceQueue.peek();
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
|
|
|
@ -819,6 +819,7 @@ public class AsyncContinuation implements AsyncContext, Continuation
|
|||
{
|
||||
synchronized (this)
|
||||
{
|
||||
_responseWrapped=!(response instanceof Response);
|
||||
doSuspend(context,request,response);
|
||||
if (request instanceof HttpServletRequest)
|
||||
{
|
||||
|
|
|
@ -193,7 +193,7 @@ public class CookieCutter
|
|||
continue;
|
||||
|
||||
case ';':
|
||||
case ',':
|
||||
// case ',':
|
||||
if (tokenstart>=0)
|
||||
value = hdr.substring(tokenstart, tokenend+1);
|
||||
else
|
||||
|
@ -239,7 +239,7 @@ public class CookieCutter
|
|||
continue;
|
||||
|
||||
case ';':
|
||||
case ',':
|
||||
// case ',':
|
||||
if (tokenstart>=0)
|
||||
{
|
||||
name = hdr.substring(tokenstart, tokenend+1);
|
||||
|
|
|
@ -265,7 +265,7 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
mex.add(e);
|
||||
}
|
||||
|
||||
if (_connectors!=null)
|
||||
if (_connectors!=null && mex.size()==0)
|
||||
{
|
||||
for (int i=0;i<_connectors.length;i++)
|
||||
{
|
||||
|
|
|
@ -21,6 +21,8 @@ import java.io.UnsupportedEncodingException;
|
|||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
@ -30,7 +32,8 @@ import org.eclipse.jetty.continuation.Continuation;
|
|||
import org.eclipse.jetty.continuation.ContinuationListener;
|
||||
import org.eclipse.jetty.continuation.ContinuationSupport;
|
||||
import org.eclipse.jetty.http.HttpMethods;
|
||||
import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
|
||||
import org.eclipse.jetty.http.gzip.CompressedResponseWrapper;
|
||||
import org.eclipse.jetty.http.gzip.AbstractCompressedStream;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
@ -222,7 +225,7 @@ public class GzipHandler extends HandlerWrapper
|
|||
}
|
||||
}
|
||||
|
||||
final GzipResponseWrapper wrappedResponse = newGzipResponseWrapper(request,response);
|
||||
final CompressedResponseWrapper wrappedResponse = newGzipResponseWrapper(request,response);
|
||||
|
||||
boolean exceptional=true;
|
||||
try
|
||||
|
@ -256,7 +259,7 @@ public class GzipHandler extends HandlerWrapper
|
|||
else if (exceptional && !response.isCommitted())
|
||||
{
|
||||
wrappedResponse.resetBuffer();
|
||||
wrappedResponse.noGzip();
|
||||
wrappedResponse.noCompression();
|
||||
}
|
||||
else
|
||||
wrappedResponse.finish();
|
||||
|
@ -276,14 +279,27 @@ public class GzipHandler extends HandlerWrapper
|
|||
* @param response the response
|
||||
* @return the gzip response wrapper
|
||||
*/
|
||||
protected GzipResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
|
||||
protected CompressedResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
return new GzipResponseWrapper(request, response)
|
||||
return new CompressedResponseWrapper(request,response)
|
||||
{
|
||||
{
|
||||
super.setMimeTypes(GzipHandler.this._mimeTypes);
|
||||
super.setBufferSize(GzipHandler.this._bufferSize);
|
||||
super.setMinGzipSize(GzipHandler.this._minGzipSize);
|
||||
super.setMinCompressSize(GzipHandler.this._minGzipSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minCompressSize) throws IOException
|
||||
{
|
||||
return new AbstractCompressedStream("gzip",request,response,contentLength,bufferSize,minCompressSize)
|
||||
{
|
||||
@Override
|
||||
protected DeflaterOutputStream createStream() throws IOException
|
||||
{
|
||||
return new GZIPOutputStream(_response.getOutputStream(),_bufferSize);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -32,7 +32,6 @@ import javax.servlet.http.HttpServletResponse;
|
|||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eclipse.jetty.http.HttpParser;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
|
@ -1280,4 +1279,51 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
response.setStatus(200);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSuspendedPipeline() throws Exception
|
||||
{
|
||||
SuspendHandler suspend = new SuspendHandler();
|
||||
suspend.setSuspendFor(30000);
|
||||
suspend.setResumeAfter(1000);
|
||||
configureServer(suspend);
|
||||
|
||||
long start=System.currentTimeMillis();
|
||||
Socket client=newSocket(HOST,_connector.getLocalPort());
|
||||
try
|
||||
{
|
||||
OutputStream os=client.getOutputStream();
|
||||
InputStream is=client.getInputStream();
|
||||
|
||||
// write an initial request
|
||||
os.write((
|
||||
"GET / HTTP/1.1\r\n"+
|
||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
||||
"\r\n"
|
||||
).getBytes());
|
||||
os.flush();
|
||||
|
||||
Thread.sleep(200);
|
||||
|
||||
// write an pipelined request
|
||||
os.write((
|
||||
"GET / HTTP/1.1\r\n"+
|
||||
"host: "+HOST+":"+_connector.getLocalPort()+"\r\n"+
|
||||
"connection: close\r\n"+
|
||||
"\r\n"
|
||||
).getBytes());
|
||||
os.flush();
|
||||
|
||||
String response=readResponse(client);
|
||||
assertThat(response,JUnitMatchers.containsString("RESUMEDHTTP/1.1 200 OK"));
|
||||
assertThat((System.currentTimeMillis()-start),greaterThanOrEqualTo(1999L));
|
||||
|
||||
// TODO This test should also check that that the CPU did not spin during the suspend.
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -669,7 +669,7 @@ public class RequestTest
|
|||
"POST / HTTP/1.1\r\n"+
|
||||
"Host: whatever\r\n"+
|
||||
"Cookie: name0=value0; name1 = value1 ; \"\\\"name2\\\"\" = \"\\\"value2\\\"\" \n" +
|
||||
"Cookie: $Version=2; name3=value3=value3;$path=/path;$domain=acme.com;$port=8080, name4=; name5 = ; name6\n" +
|
||||
"Cookie: $Version=2; name3=value3=value3;$path=/path;$domain=acme.com;$port=8080; name4=; name5 = ; name6\n" +
|
||||
"Cookie: name7=value7;\n" +
|
||||
"Connection: close\r\n"+
|
||||
"\r\n");
|
||||
|
@ -694,6 +694,20 @@ public class RequestTest
|
|||
assertEquals("", cookies.get(6).getValue());
|
||||
assertEquals("name7", cookies.get(7).getName());
|
||||
assertEquals("value7", cookies.get(7).getValue());
|
||||
|
||||
cookies.clear();
|
||||
response=_connector.getResponses(
|
||||
"GET /other HTTP/1.1\n"+
|
||||
"Host: whatever\n"+
|
||||
"Other: header\n"+
|
||||
"Cookie: __utmz=14316.133020.1.1.utr=gna.de|ucn=(real)|utd=reral|utct=/games/hen-one,gnt-50-ba-keys:key,2072262.html\n"+
|
||||
"\n"
|
||||
);
|
||||
assertTrue(response.startsWith("HTTP/1.1 200 OK"));
|
||||
assertEquals(1,cookies.size());
|
||||
assertEquals("__utmz", cookies.get(0).getName());
|
||||
assertEquals("14316.133020.1.1.utr=gna.de|ucn=(real)|utd=reral|utct=/games/hen-one,gnt-50-ba-keys:key,2072262.html", cookies.get(0).getValue());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -31,6 +31,12 @@ public class SelectChannelServerTest extends HttpServerTestBase
|
|||
{
|
||||
super.testCommittedError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testSuspendedPipeline() throws Exception
|
||||
{
|
||||
super.testSuspendedPipeline();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -121,8 +121,7 @@ class SuspendHandler extends HandlerWrapper
|
|||
try
|
||||
{
|
||||
Thread.sleep(_resumeAfter);
|
||||
if(((HttpServletRequest)asyncContext.getRequest()).getSession(true).getId()!=null)
|
||||
asyncContext.dispatch();
|
||||
asyncContext.dispatch();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
|
|
|
@ -99,8 +99,6 @@ public class SSLEngineTest
|
|||
connector.setRequestHeaderSize(512);
|
||||
|
||||
server.setConnectors(new Connector[]{connector });
|
||||
server.setHandler(new HelloWorldHandler());
|
||||
server.start();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
|
@ -109,10 +107,15 @@ public class SSLEngineTest
|
|||
server.stop();
|
||||
server.join();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testBigResponse() throws Exception
|
||||
{
|
||||
server.stop();
|
||||
server.setHandler(new HelloWorldHandler());
|
||||
server.start();
|
||||
|
||||
SSLContext ctx=SSLContext.getInstance("TLS");
|
||||
ctx.init(null,SslContextFactory.TRUST_ALL_CERTS,new java.security.SecureRandom());
|
||||
|
||||
|
@ -123,7 +126,7 @@ public class SSLEngineTest
|
|||
|
||||
String request =
|
||||
"GET /?dump=102400 HTTP/1.1\r\n"+
|
||||
"Host: localhost:8080\r\n"+
|
||||
"Host: localhost:"+port+"\r\n"+
|
||||
"Connection: close\r\n"+
|
||||
"\r\n";
|
||||
|
||||
|
@ -138,6 +141,10 @@ public class SSLEngineTest
|
|||
@Test
|
||||
public void testRequestJettyHttps() throws Exception
|
||||
{
|
||||
server.stop();
|
||||
server.setHandler(new HelloWorldHandler());
|
||||
server.start();
|
||||
|
||||
final int loops=10;
|
||||
final int numConns=10;
|
||||
|
||||
|
@ -204,8 +211,7 @@ public class SSLEngineTest
|
|||
@Test
|
||||
public void testServletPost() throws Exception
|
||||
{
|
||||
stopServer();
|
||||
|
||||
server.stop();
|
||||
StreamHandler handler = new StreamHandler();
|
||||
server.setHandler(handler);
|
||||
server.start();
|
||||
|
@ -308,6 +314,7 @@ public class SSLEngineTest
|
|||
{
|
||||
ServletOutputStream out=response.getOutputStream();
|
||||
byte[] buf = new byte[Integer.valueOf(request.getParameter("dump"))];
|
||||
// System.err.println("DUMP "+buf.length);
|
||||
for (int i=0;i<buf.length;i++)
|
||||
buf[i]=(byte)('0'+(i%10));
|
||||
out.write(buf);
|
||||
|
|
|
@ -15,20 +15,29 @@ package org.eclipse.jetty.server.ssl;
|
|||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.security.KeyStore;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
|
||||
|
||||
import org.eclipse.jetty.io.AsyncEndPoint;
|
||||
import org.eclipse.jetty.io.Connection;
|
||||
import org.eclipse.jetty.io.nio.SslConnection;
|
||||
import org.eclipse.jetty.server.HttpServerTestBase;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.hamcrest.Matchers.lessThan;
|
||||
|
||||
/**
|
||||
* HttpServer Tester.
|
||||
|
@ -46,11 +55,28 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
|
|||
return __sslContext.getSocketFactory().createSocket(host,port);
|
||||
}
|
||||
|
||||
private static final AtomicInteger _handlecount = new AtomicInteger();
|
||||
|
||||
@BeforeClass
|
||||
public static void init() throws Exception
|
||||
{
|
||||
SslSelectChannelConnector connector = new SslSelectChannelConnector();
|
||||
SslSelectChannelConnector connector = new SslSelectChannelConnector()
|
||||
{
|
||||
@Override
|
||||
protected SslConnection newSslConnection(AsyncEndPoint endPoint, SSLEngine engine)
|
||||
{
|
||||
return new SslConnection(engine, endPoint)
|
||||
{
|
||||
@Override
|
||||
public Connection handle() throws IOException
|
||||
{
|
||||
_handlecount.incrementAndGet();
|
||||
return super.handle();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
String keystorePath = System.getProperty("basedir",".") + "/src/test/resources/keystore";
|
||||
SslContextFactory cf = connector.getSslContextFactory();
|
||||
cf.setKeyStorePath(keystorePath);
|
||||
|
@ -69,7 +95,6 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
|
|||
__sslContext = SSLContext.getInstance("TLS");
|
||||
__sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
HttpsURLConnection.setDefaultHostnameVerifier(__hostnameverifier);
|
||||
|
@ -105,7 +130,6 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
|
|||
{
|
||||
OutputStream os=client.getOutputStream();
|
||||
|
||||
|
||||
int last=0;
|
||||
|
||||
// Write out the fragments
|
||||
|
@ -137,12 +161,17 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Ignore
|
||||
public void testAvailable() throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void testSuspendedPipeline() throws Exception
|
||||
{
|
||||
_handlecount.set(0);
|
||||
super.testSuspendedPipeline();
|
||||
assertThat(_handlecount.get(),lessThan(50));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
|
|
|
@ -583,7 +583,8 @@ public class ServletHandler extends ScopedHandler
|
|||
}
|
||||
finally
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
if (servlet_holder!=null)
|
||||
baseRequest.setHandled(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.eclipse.jetty.servlet;
|
|||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
|
@ -12,6 +13,7 @@ import javax.servlet.ServletException;
|
|||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpServletResponseWrapper;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
|
@ -223,17 +225,20 @@ public class AsyncContextTest
|
|||
}
|
||||
else
|
||||
{
|
||||
boolean wrapped = false;
|
||||
final AsyncContext asyncContext;
|
||||
if (request.getParameter("dispatchRequestResponse") != null)
|
||||
{
|
||||
asyncContext = request.startAsync(request,response);
|
||||
wrapped = true;
|
||||
asyncContext = request.startAsync(request, new Wrapper(response));
|
||||
}
|
||||
else
|
||||
{
|
||||
asyncContext = request.startAsync();
|
||||
}
|
||||
|
||||
new Thread(new DispatchingRunnable(asyncContext)).start();
|
||||
|
||||
new Thread(new DispatchingRunnable(asyncContext, wrapped)).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -241,14 +246,18 @@ public class AsyncContextTest
|
|||
private class DispatchingRunnable implements Runnable
|
||||
{
|
||||
private AsyncContext asyncContext;
|
||||
private boolean wrapped;
|
||||
|
||||
public DispatchingRunnable(AsyncContext asyncContext)
|
||||
public DispatchingRunnable(AsyncContext asyncContext, boolean wrapped)
|
||||
{
|
||||
this.asyncContext = asyncContext;
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
if (wrapped)
|
||||
assertTrue(asyncContext.getResponse() instanceof Wrapper);
|
||||
asyncContext.dispatch();
|
||||
}
|
||||
}
|
||||
|
@ -347,4 +356,13 @@ public class AsyncContextTest
|
|||
}
|
||||
}
|
||||
|
||||
private class Wrapper extends HttpServletResponseWrapper
|
||||
{
|
||||
public Wrapper (HttpServletResponse response)
|
||||
{
|
||||
super(response);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-servlets</artifactId>
|
||||
|
|
|
@ -992,7 +992,7 @@ public class DoSFilter implements Filter
|
|||
if (_rateTrackers != null && _trackerTimeoutQ != null)
|
||||
{
|
||||
long now = _trackerTimeoutQ.getNow();
|
||||
int latestIndex = _next == 0 ? 3 : (_next - 1 ) % _timestamps.length;
|
||||
int latestIndex = _next == 0 ? (_timestamps.length-1) : (_next - 1 );
|
||||
long last=_timestamps[latestIndex];
|
||||
boolean hasRecentRequest = last != 0 && (now-last)<1000L;
|
||||
|
||||
|
|
|
@ -13,14 +13,12 @@
|
|||
package org.eclipse.jetty.servlets;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
|
@ -34,14 +32,16 @@ import org.eclipse.jetty.continuation.Continuation;
|
|||
import org.eclipse.jetty.continuation.ContinuationListener;
|
||||
import org.eclipse.jetty.continuation.ContinuationSupport;
|
||||
import org.eclipse.jetty.http.HttpMethods;
|
||||
import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
|
||||
import org.eclipse.jetty.http.gzip.CompressedResponseWrapper;
|
||||
import org.eclipse.jetty.http.gzip.AbstractCompressedStream;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** GZIP Filter
|
||||
* This filter will gzip the content of a response iff: <ul>
|
||||
* This filter will gzip or deflate the content of a response if: <ul>
|
||||
* <li>The filter is mapped to a matching path</li>
|
||||
* <li>accept-encoding header is set to either gzip, deflate or a combination of those</li>
|
||||
* <li>The response status code is >=200 and <300
|
||||
* <li>The content length is unknown or more than the <code>minGzipSize</code> initParameter or the minGzipSize is 0(default)</li>
|
||||
* <li>The content-type is in the comma separated list of mimeTypes set in the <code>mimeTypes</code> initParameter or
|
||||
|
@ -50,8 +50,11 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* If both gzip and deflate are specified in the accept-encoding header, then gzip will be used.
|
||||
* </p>
|
||||
* <p>
|
||||
* Compressing the content can greatly improve the network bandwidth usage, but at a cost of memory and
|
||||
* CPU cycles. If this filter is mapped for static content, then use of efficient direct NIO may be
|
||||
* CPU cycles. If this filter is mapped for static content, then use of efficient direct NIO may be
|
||||
* prevented, thus use of the gzip mechanism of the {@link org.eclipse.jetty.servlet.DefaultServlet} is
|
||||
* advised instead.
|
||||
* </p>
|
||||
|
@ -64,6 +67,8 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
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;
|
||||
|
@ -144,7 +149,7 @@ public class GzipFilter extends UserAgentFilter
|
|||
public void destroy()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.servlets.UserAgentFilter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
|
||||
|
@ -156,9 +161,8 @@ public class GzipFilter extends UserAgentFilter
|
|||
HttpServletRequest request=(HttpServletRequest)req;
|
||||
HttpServletResponse response=(HttpServletResponse)res;
|
||||
|
||||
String ae = request.getHeader("accept-encoding");
|
||||
if (ae != null && ae.indexOf("gzip")>=0 && !response.containsHeader("Content-Encoding")
|
||||
&& !HttpMethods.HEAD.equalsIgnoreCase(request.getMethod()))
|
||||
String compressionType = selectCompression(request.getHeader("accept-encoding"));
|
||||
if (compressionType!=null && !response.containsHeader("Content-Encoding") && !HttpMethods.HEAD.equalsIgnoreCase(request.getMethod()))
|
||||
{
|
||||
String ua = getUserAgent(request);
|
||||
if (isExcludedAgent(ua))
|
||||
|
@ -172,8 +176,8 @@ public class GzipFilter extends UserAgentFilter
|
|||
super.doFilter(request,response,chain);
|
||||
return;
|
||||
}
|
||||
|
||||
final GzipResponseWrapper wrappedResponse=newGzipResponseWrapper(request,response);
|
||||
|
||||
CompressedResponseWrapper wrappedResponse = createWrappedResponse(request,response,compressionType);
|
||||
|
||||
boolean exceptional=true;
|
||||
try
|
||||
|
@ -186,28 +190,12 @@ public class GzipFilter extends UserAgentFilter
|
|||
Continuation continuation = ContinuationSupport.getContinuation(request);
|
||||
if (continuation.isSuspended() && continuation.isResponseWrapped())
|
||||
{
|
||||
continuation.addContinuationListener(new ContinuationListener()
|
||||
{
|
||||
public void onComplete(Continuation continuation)
|
||||
{
|
||||
try
|
||||
{
|
||||
wrappedResponse.finish();
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void onTimeout(Continuation continuation)
|
||||
{}
|
||||
});
|
||||
continuation.addContinuationListener(new ContinuationListenerWaitingForWrappedResponseToFinish(wrappedResponse));
|
||||
}
|
||||
else if (exceptional && !response.isCommitted())
|
||||
{
|
||||
wrappedResponse.resetBuffer();
|
||||
wrappedResponse.noGzip();
|
||||
wrappedResponse.noCompression();
|
||||
}
|
||||
else
|
||||
wrappedResponse.finish();
|
||||
|
@ -218,7 +206,102 @@ public class GzipFilter extends UserAgentFilter
|
|||
super.doFilter(request,response,chain);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private String selectCompression(String encodingHeader)
|
||||
{
|
||||
// TODO, this could be a little more robust.
|
||||
// prefer gzip over deflate
|
||||
if (encodingHeader!=null)
|
||||
{
|
||||
if (encodingHeader.toLowerCase().contains(GZIP))
|
||||
return GZIP;
|
||||
else if (encodingHeader.toLowerCase().contains(DEFLATE))
|
||||
return DEFLATE;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, final String compressionType)
|
||||
{
|
||||
CompressedResponseWrapper wrappedResponse = null;
|
||||
if (compressionType.equals(GZIP))
|
||||
{
|
||||
wrappedResponse = new CompressedResponseWrapper(request,response)
|
||||
{
|
||||
@Override
|
||||
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minCompressSize) throws IOException
|
||||
{
|
||||
return new AbstractCompressedStream(compressionType,request,response,contentLength,bufferSize,minCompressSize)
|
||||
{
|
||||
@Override
|
||||
protected DeflaterOutputStream createStream() throws IOException
|
||||
{
|
||||
return new GZIPOutputStream(_response.getOutputStream(),_bufferSize);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
else if (compressionType.equals(DEFLATE))
|
||||
{
|
||||
wrappedResponse = new CompressedResponseWrapper(request,response)
|
||||
{
|
||||
@Override
|
||||
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minCompressSize) throws IOException
|
||||
{
|
||||
return new AbstractCompressedStream(compressionType,request,response,contentLength,bufferSize,minCompressSize)
|
||||
{
|
||||
@Override
|
||||
protected DeflaterOutputStream createStream() throws IOException
|
||||
{
|
||||
return new DeflaterOutputStream(_response.getOutputStream());
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalStateException(compressionType + " not supported");
|
||||
}
|
||||
configureWrappedResponse(wrappedResponse);
|
||||
return wrappedResponse;
|
||||
}
|
||||
|
||||
protected void configureWrappedResponse(CompressedResponseWrapper wrappedResponse)
|
||||
{
|
||||
wrappedResponse.setMimeTypes(_mimeTypes);
|
||||
wrappedResponse.setBufferSize(_bufferSize);
|
||||
wrappedResponse.setMinCompressSize(_minGzipSize);
|
||||
}
|
||||
|
||||
private class ContinuationListenerWaitingForWrappedResponseToFinish implements ContinuationListener{
|
||||
|
||||
private CompressedResponseWrapper wrappedResponse;
|
||||
|
||||
public ContinuationListenerWaitingForWrappedResponseToFinish(CompressedResponseWrapper wrappedResponse)
|
||||
{
|
||||
this.wrappedResponse = wrappedResponse;
|
||||
}
|
||||
|
||||
public void onComplete(Continuation continuation)
|
||||
{
|
||||
try
|
||||
{
|
||||
wrappedResponse.finish();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void onTimeout(Continuation continuation)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the UserAgent is excluded
|
||||
*
|
||||
|
@ -275,42 +358,4 @@ public class GzipFilter extends UserAgentFilter
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows derived implementations to replace ResponseWrapper implementation.
|
||||
*
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @return the gzip response wrapper
|
||||
*/
|
||||
protected GzipResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
return new GzipResponseWrapper(request, response)
|
||||
{
|
||||
{
|
||||
setMimeTypes(GzipFilter.this._mimeTypes);
|
||||
setBufferSize(GzipFilter.this._bufferSize);
|
||||
setMinGzipSize(GzipFilter.this._minGzipSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
|
||||
{
|
||||
return GzipFilter.this.newWriter(out,encoding);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows derived implementations to replace PrintWriter implementation.
|
||||
*
|
||||
* @param out the out
|
||||
* @param encoding the encoding
|
||||
* @return the prints the writer
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
|
||||
{
|
||||
return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,18 +18,18 @@ import java.io.OutputStream;
|
|||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
|
||||
import org.eclipse.jetty.http.gzip.GzipStream;
|
||||
import org.eclipse.jetty.http.gzip.CompressedResponseWrapper;
|
||||
import org.eclipse.jetty.http.gzip.AbstractCompressedStream;
|
||||
import org.eclipse.jetty.io.UncheckedPrintWriter;
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Includable GZip Filter.
|
||||
* This extension to the {@link GzipFilter} that uses Jetty features to allow
|
||||
|
@ -56,61 +56,82 @@ public class IncludableGzipFilter extends GzipFilter
|
|||
_uncheckedPrintWriter=Boolean.valueOf(tmp).booleanValue();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.servlets.GzipFilter#createWrappedResponse(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
protected GzipResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
|
||||
protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, final String compressionType)
|
||||
{
|
||||
return new IncludableResponseWrapper(request,response);
|
||||
CompressedResponseWrapper wrappedResponse = null;
|
||||
if (compressionType.equals(GZIP))
|
||||
{
|
||||
wrappedResponse = new IncludableResponseWrapper(request,response)
|
||||
{
|
||||
@Override
|
||||
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minCompressSize) throws IOException
|
||||
{
|
||||
return new AbstractCompressedStream(compressionType,request,response,contentLength,bufferSize,minCompressSize)
|
||||
{
|
||||
@Override
|
||||
protected DeflaterOutputStream createStream() throws IOException
|
||||
{
|
||||
return new GZIPOutputStream(_response.getOutputStream(),_bufferSize);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
else if (compressionType.equals(DEFLATE))
|
||||
{
|
||||
wrappedResponse = new IncludableResponseWrapper(request,response)
|
||||
{
|
||||
@Override
|
||||
protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minCompressSize) throws IOException
|
||||
{
|
||||
return new AbstractCompressedStream(compressionType,request,response,contentLength,bufferSize,minCompressSize)
|
||||
{
|
||||
@Override
|
||||
protected DeflaterOutputStream createStream() throws IOException
|
||||
{
|
||||
return new DeflaterOutputStream(_response.getOutputStream());
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalStateException(compressionType + " not supported");
|
||||
}
|
||||
configureWrappedResponse(wrappedResponse);
|
||||
return wrappedResponse;
|
||||
}
|
||||
|
||||
public class IncludableResponseWrapper extends GzipResponseWrapper
|
||||
|
||||
|
||||
// Extend CompressedResponseWrapper to be able to set headers during include and to create unchecked printwriters
|
||||
private abstract class IncludableResponseWrapper extends CompressedResponseWrapper
|
||||
{
|
||||
public IncludableResponseWrapper(HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
super(request,response);
|
||||
|
||||
super.setMimeTypes(IncludableGzipFilter.this._mimeTypes);
|
||||
super.setBufferSize(IncludableGzipFilter.this._bufferSize);
|
||||
super.setMinGzipSize(IncludableGzipFilter.this._minGzipSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GzipStream newGzipStream(HttpServletRequest request,HttpServletResponse response,long contentLength,int bufferSize, int minGzipSize) throws IOException
|
||||
public void setHeader(String name,String value)
|
||||
{
|
||||
return new IncludableGzipStream(request,response,contentLength,bufferSize,minGzipSize);
|
||||
super.setHeader(name,value);
|
||||
HttpServletResponse response = (HttpServletResponse)getResponse();
|
||||
if (!response.containsHeader(name))
|
||||
response.setHeader("org.eclipse.jetty.server.include."+name,value);;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
|
||||
protected PrintWriter newWriter(OutputStream out, String encoding) throws UnsupportedEncodingException
|
||||
{
|
||||
return IncludableGzipFilter.this.newWriter(out,encoding);
|
||||
}
|
||||
}
|
||||
|
||||
public class IncludableGzipStream extends GzipStream
|
||||
{
|
||||
public IncludableGzipStream(HttpServletRequest request, HttpServletResponse response, long contentLength, int bufferSize, int minGzipSize)
|
||||
throws IOException
|
||||
{
|
||||
super(request,response,contentLength,bufferSize,minGzipSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean setContentEncodingGzip()
|
||||
{
|
||||
if (_request.getAttribute("javax.servlet.include.request_uri")!=null)
|
||||
_response.setHeader("org.eclipse.jetty.server.include.Content-Encoding", "gzip");
|
||||
else
|
||||
_response.setHeader("Content-Encoding", "gzip");
|
||||
|
||||
return _response.containsHeader("Content-Encoding");
|
||||
if (_uncheckedPrintWriter)
|
||||
return encoding == null?new UncheckedPrintWriter(out):new UncheckedPrintWriter(new OutputStreamWriter(out,encoding));
|
||||
return super.newWriter(out,encoding);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
|
||||
{
|
||||
if (_uncheckedPrintWriter)
|
||||
return encoding==null?new UncheckedPrintWriter(out):new UncheckedPrintWriter(new OutputStreamWriter(out,encoding));
|
||||
return super.newWriter(out,encoding);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -414,7 +414,7 @@ public class ProxyServlet implements Servlet
|
|||
if (request.getQueryString() != null)
|
||||
uri += "?" + request.getQueryString();
|
||||
|
||||
HttpURI url = proxyHttpURI(request.getScheme(),request.getServerName(),request.getServerPort(),uri);
|
||||
HttpURI url = proxyHttpURI(request,uri);
|
||||
|
||||
if (debug != 0)
|
||||
_log.debug(debug + " proxy " + uri + "-->" + url);
|
||||
|
@ -677,6 +677,11 @@ public class ProxyServlet implements Servlet
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected HttpURI proxyHttpURI(HttpServletRequest request, String uri) throws MalformedURLException
|
||||
{
|
||||
return proxyHttpURI(request.getScheme(), request.getServerName(), request.getServerPort(), uri);
|
||||
}
|
||||
|
||||
protected HttpURI proxyHttpURI(String scheme, String serverName, int serverPort, String uri) throws MalformedURLException
|
||||
{
|
||||
if (!validateDestination(serverName,uri))
|
||||
|
|
|
@ -6,7 +6,7 @@ import java.util.List;
|
|||
import javax.servlet.Servlet;
|
||||
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
|
||||
import org.eclipse.jetty.http.gzip.CompressedResponseWrapper;
|
||||
import org.eclipse.jetty.servlet.FilterHolder;
|
||||
import org.eclipse.jetty.servlets.gzip.GzipTester;
|
||||
import org.eclipse.jetty.servlets.gzip.TestServletLengthStreamTypeWrite;
|
||||
|
@ -48,32 +48,42 @@ public class GzipFilterContentLengthTest
|
|||
{
|
||||
return Arrays.asList(new Object[][]
|
||||
{
|
||||
{ TestServletLengthStreamTypeWrite.class },
|
||||
{ TestServletLengthTypeStreamWrite.class },
|
||||
{ TestServletStreamLengthTypeWrite.class },
|
||||
{ TestServletStreamTypeLengthWrite.class },
|
||||
{ TestServletTypeLengthStreamWrite.class },
|
||||
{ TestServletTypeStreamLengthWrite.class } });
|
||||
{ TestServletLengthStreamTypeWrite.class, GzipFilter.GZIP },
|
||||
{ TestServletLengthTypeStreamWrite.class, GzipFilter.GZIP },
|
||||
{ TestServletStreamLengthTypeWrite.class, GzipFilter.GZIP },
|
||||
{ TestServletStreamTypeLengthWrite.class, GzipFilter.GZIP },
|
||||
{ TestServletTypeLengthStreamWrite.class, GzipFilter.GZIP },
|
||||
{ TestServletTypeStreamLengthWrite.class, GzipFilter.GZIP },
|
||||
{ TestServletLengthStreamTypeWrite.class, GzipFilter.DEFLATE },
|
||||
{ TestServletLengthTypeStreamWrite.class, GzipFilter.DEFLATE },
|
||||
{ TestServletStreamLengthTypeWrite.class, GzipFilter.DEFLATE },
|
||||
{ TestServletStreamTypeLengthWrite.class, GzipFilter.DEFLATE },
|
||||
{ TestServletTypeLengthStreamWrite.class, GzipFilter.DEFLATE },
|
||||
{ TestServletTypeStreamLengthWrite.class, GzipFilter.DEFLATE }
|
||||
});
|
||||
}
|
||||
|
||||
private static final int LARGE = GzipResponseWrapper.DEFAULT_BUFFER_SIZE * 8;
|
||||
private static final int MEDIUM = GzipResponseWrapper.DEFAULT_BUFFER_SIZE;
|
||||
private static final int SMALL = GzipResponseWrapper.DEFAULT_BUFFER_SIZE / 4;
|
||||
private static final int TINY = GzipResponseWrapper.DEFAULT_MIN_GZIP_SIZE / 2;
|
||||
private static final int LARGE = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE * 8;
|
||||
private static final int MEDIUM = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE;
|
||||
private static final int SMALL = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE / 4;
|
||||
private static final int TINY = CompressedResponseWrapper.DEFAULT_MIN_COMPRESS_SIZE/ 2;
|
||||
|
||||
private String compressionType;
|
||||
|
||||
public GzipFilterContentLengthTest(Class<? extends Servlet> testServlet, String compressionType)
|
||||
{
|
||||
this.testServlet = testServlet;
|
||||
this.compressionType = compressionType;
|
||||
}
|
||||
|
||||
@Rule
|
||||
public TestingDir testingdir = new TestingDir();
|
||||
|
||||
private Class<? extends Servlet> testServlet;
|
||||
|
||||
public GzipFilterContentLengthTest(Class<? extends Servlet> testServlet)
|
||||
{
|
||||
this.testServlet = testServlet;
|
||||
}
|
||||
|
||||
private void assertIsGzipCompressed(String filename, int filesize) throws Exception
|
||||
{
|
||||
GzipTester tester = new GzipTester(testingdir);
|
||||
GzipTester tester = new GzipTester(testingdir, compressionType);
|
||||
|
||||
File testfile = tester.prepareServerFile(testServlet.getSimpleName() + "-" + filename,filesize);
|
||||
|
||||
|
@ -93,7 +103,7 @@ public class GzipFilterContentLengthTest
|
|||
|
||||
private void assertIsNotGzipCompressed(String filename, int filesize) throws Exception
|
||||
{
|
||||
GzipTester tester = new GzipTester(testingdir);
|
||||
GzipTester tester = new GzipTester(testingdir, compressionType);
|
||||
|
||||
File testfile = tester.prepareServerFile(testServlet.getSimpleName() + "-" + filename,filesize);
|
||||
|
||||
|
|
|
@ -31,22 +31,41 @@ public class GzipFilterDefaultNoRecompressTest
|
|||
return Arrays.asList(new Object[][]
|
||||
{
|
||||
// Some already compressed files
|
||||
{ "test_quotes.gz", "application/gzip" },
|
||||
{ "test_quotes.bz2", "application/bzip2" },
|
||||
{ "test_quotes.zip", "application/zip" },
|
||||
{ "test_quotes.rar", "application/octet-stream" },
|
||||
{ "test_quotes.gz", "application/gzip", GzipFilter.GZIP },
|
||||
{ "test_quotes.bz2", "application/bzip2", GzipFilter.GZIP },
|
||||
{ "test_quotes.zip", "application/zip", GzipFilter.GZIP },
|
||||
{ "test_quotes.rar", "application/octet-stream", GzipFilter.GZIP },
|
||||
// Some images (common first)
|
||||
{ "jetty_logo.png", "image/png" },
|
||||
{ "jetty_logo.gif", "image/gif" },
|
||||
{ "jetty_logo.jpeg", "image/jpeg" },
|
||||
{ "jetty_logo.jpg", "image/jpeg" },
|
||||
{ "jetty_logo.png", "image/png", GzipFilter.GZIP },
|
||||
{ "jetty_logo.gif", "image/gif", GzipFilter.GZIP },
|
||||
{ "jetty_logo.jpeg", "image/jpeg", GzipFilter.GZIP },
|
||||
{ "jetty_logo.jpg", "image/jpeg", GzipFilter.GZIP },
|
||||
// Lesser encountered images (usually found being requested from non-browser clients)
|
||||
{ "jetty_logo.bmp", "image/bmp" },
|
||||
{ "jetty_logo.tga", "application/tga" },
|
||||
{ "jetty_logo.tif", "image/tiff" },
|
||||
{ "jetty_logo.tiff", "image/tiff" },
|
||||
{ "jetty_logo.xcf", "image/xcf" },
|
||||
{ "jetty_logo.jp2", "image/jpeg2000" } });
|
||||
{ "jetty_logo.bmp", "image/bmp", GzipFilter.GZIP },
|
||||
{ "jetty_logo.tga", "application/tga", GzipFilter.GZIP },
|
||||
{ "jetty_logo.tif", "image/tiff", GzipFilter.GZIP },
|
||||
{ "jetty_logo.tiff", "image/tiff", GzipFilter.GZIP },
|
||||
{ "jetty_logo.xcf", "image/xcf", GzipFilter.GZIP },
|
||||
{ "jetty_logo.jp2", "image/jpeg2000", GzipFilter.GZIP },
|
||||
|
||||
// Same tests again for deflate
|
||||
// Some already compressed files
|
||||
{ "test_quotes.gz", "application/gzip", GzipFilter.DEFLATE },
|
||||
{ "test_quotes.bz2", "application/bzip2", GzipFilter.DEFLATE },
|
||||
{ "test_quotes.zip", "application/zip", GzipFilter.DEFLATE },
|
||||
{ "test_quotes.rar", "application/octet-stream", GzipFilter.DEFLATE },
|
||||
// Some images (common first)
|
||||
{ "jetty_logo.png", "image/png", GzipFilter.DEFLATE },
|
||||
{ "jetty_logo.gif", "image/gif", GzipFilter.DEFLATE },
|
||||
{ "jetty_logo.jpeg", "image/jpeg", GzipFilter.DEFLATE },
|
||||
{ "jetty_logo.jpg", "image/jpeg", GzipFilter.DEFLATE },
|
||||
// Lesser encountered images (usually found being requested from non-browser clients)
|
||||
{ "jetty_logo.bmp", "image/bmp", GzipFilter.DEFLATE },
|
||||
{ "jetty_logo.tga", "application/tga", GzipFilter.DEFLATE },
|
||||
{ "jetty_logo.tif", "image/tiff", GzipFilter.DEFLATE },
|
||||
{ "jetty_logo.tiff", "image/tiff", GzipFilter.DEFLATE },
|
||||
{ "jetty_logo.xcf", "image/xcf", GzipFilter.DEFLATE },
|
||||
{ "jetty_logo.jp2", "image/jpeg2000", GzipFilter.DEFLATE } });
|
||||
}
|
||||
|
||||
@Rule
|
||||
|
@ -54,17 +73,19 @@ public class GzipFilterDefaultNoRecompressTest
|
|||
|
||||
private String alreadyCompressedFilename;
|
||||
private String expectedContentType;
|
||||
private String compressionType;
|
||||
|
||||
public GzipFilterDefaultNoRecompressTest(String testFilename, String expectedContentType)
|
||||
public GzipFilterDefaultNoRecompressTest(String testFilename, String expectedContentType, String compressionType)
|
||||
{
|
||||
this.alreadyCompressedFilename = testFilename;
|
||||
this.expectedContentType = expectedContentType;
|
||||
this.compressionType = compressionType;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotGzipFiltered_Default_AlreadyCompressed() throws Exception
|
||||
{
|
||||
GzipTester tester = new GzipTester(testingdir);
|
||||
GzipTester tester = new GzipTester(testingdir, compressionType);
|
||||
|
||||
copyTestFileToServer(alreadyCompressedFilename);
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package org.eclipse.jetty.servlets;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
|
@ -8,23 +10,47 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.http.gzip.GzipResponseWrapper;
|
||||
import org.eclipse.jetty.http.gzip.CompressedResponseWrapper;
|
||||
import org.eclipse.jetty.servlet.DefaultServlet;
|
||||
import org.eclipse.jetty.servlet.FilterHolder;
|
||||
import org.eclipse.jetty.servlets.gzip.GzipTester;
|
||||
import org.eclipse.jetty.toolchain.test.TestingDir;
|
||||
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 GzipFilter support built into the {@link DefaultServlet}
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class GzipFilterDefaultTest
|
||||
{
|
||||
@Parameters
|
||||
public static Collection<String[]> data()
|
||||
{
|
||||
String[][] data = new String[][]
|
||||
{
|
||||
{ GzipFilter.GZIP },
|
||||
{ GzipFilter.DEFLATE }
|
||||
};
|
||||
|
||||
return Arrays.asList(data);
|
||||
}
|
||||
|
||||
private String compressionType;
|
||||
|
||||
public GzipFilterDefaultTest(String compressionType)
|
||||
{
|
||||
this.compressionType = compressionType;
|
||||
}
|
||||
|
||||
|
||||
public static class HttpStatusServlet extends HttpServlet
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private int _status = 204;
|
||||
|
||||
public HttpStatusServlet()
|
||||
|
@ -50,10 +76,10 @@ public class GzipFilterDefaultTest
|
|||
@Test
|
||||
public void testIsGzipCompressedTiny() throws Exception
|
||||
{
|
||||
GzipTester tester = new GzipTester(testingdir);
|
||||
GzipTester tester = new GzipTester(testingdir, compressionType);
|
||||
|
||||
// Test content that is smaller than the buffer.
|
||||
int filesize = GzipResponseWrapper.DEFAULT_BUFFER_SIZE / 4;
|
||||
int filesize = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE / 4;
|
||||
tester.prepareServerFile("file.txt",filesize);
|
||||
|
||||
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
|
||||
|
@ -73,10 +99,10 @@ public class GzipFilterDefaultTest
|
|||
@Test
|
||||
public void testIsGzipCompressedLarge() throws Exception
|
||||
{
|
||||
GzipTester tester = new GzipTester(testingdir);
|
||||
GzipTester tester = new GzipTester(testingdir, compressionType);
|
||||
|
||||
// Test content that is smaller than the buffer.
|
||||
int filesize = GzipResponseWrapper.DEFAULT_BUFFER_SIZE * 4;
|
||||
int filesize = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE * 4;
|
||||
tester.prepareServerFile("file.txt",filesize);
|
||||
|
||||
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
|
||||
|
@ -96,10 +122,10 @@ public class GzipFilterDefaultTest
|
|||
@Test
|
||||
public void testIsNotGzipCompressed() throws Exception
|
||||
{
|
||||
GzipTester tester = new GzipTester(testingdir);
|
||||
GzipTester tester = new GzipTester(testingdir, compressionType);
|
||||
|
||||
// Test content that is smaller than the buffer.
|
||||
int filesize = GzipResponseWrapper.DEFAULT_BUFFER_SIZE * 4;
|
||||
int filesize = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE * 4;
|
||||
tester.prepareServerFile("file.mp3",filesize);
|
||||
|
||||
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
|
||||
|
@ -119,7 +145,7 @@ public class GzipFilterDefaultTest
|
|||
@Test
|
||||
public void testIsNotGzipCompressedHttpStatus() throws Exception
|
||||
{
|
||||
GzipTester tester = new GzipTester(testingdir);
|
||||
GzipTester tester = new GzipTester(testingdir, compressionType);
|
||||
|
||||
// Test error code 204
|
||||
FilterHolder holder = tester.setContentServlet(HttpStatusServlet.class);
|
||||
|
@ -140,13 +166,13 @@ public class GzipFilterDefaultTest
|
|||
@Test
|
||||
public void testUserAgentExclusion() throws Exception
|
||||
{
|
||||
GzipTester tester = new GzipTester(testingdir);
|
||||
GzipTester tester = new GzipTester(testingdir, compressionType);
|
||||
|
||||
FilterHolder holder = tester.setContentServlet(DefaultServlet.class);
|
||||
holder.setInitParameter("excludedAgents", "foo");
|
||||
tester.setUserAgent("foo");
|
||||
|
||||
int filesize = GzipResponseWrapper.DEFAULT_BUFFER_SIZE * 4;
|
||||
int filesize = CompressedResponseWrapper.DEFAULT_BUFFER_SIZE * 4;
|
||||
tester.prepareServerFile("file.txt",filesize);
|
||||
|
||||
try
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
package org.eclipse.jetty.servlets;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
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.InflaterInputStream;
|
||||
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
|
@ -25,21 +30,46 @@ 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.Assert;
|
||||
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
|
||||
|
@ -86,7 +116,7 @@ public class GzipWithPipeliningTest
|
|||
testingdir.ensureEmpty();
|
||||
File outputDir = testingdir.getDir();
|
||||
|
||||
PipelineHelper client = new PipelineHelper(serverUri);
|
||||
PipelineHelper client = new PipelineHelper(serverUri, encodingHeader);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -95,7 +125,7 @@ public class GzipWithPipeliningTest
|
|||
|
||||
// Size of content, as it exists on disk, without gzip compression.
|
||||
long rawsize = txtFile.length() + pngFile.length();
|
||||
Assert.assertThat("Ensure that we have sufficient file size to trigger chunking",rawsize,greaterThan(300000L));
|
||||
assertThat("Ensure that we have sufficient file size to trigger chunking",rawsize,greaterThan(300000L));
|
||||
|
||||
String respHeader;
|
||||
|
||||
|
@ -106,8 +136,9 @@ public class GzipWithPipeliningTest
|
|||
|
||||
respHeader = client.readResponseHeader();
|
||||
System.out.println("Response Header #1 --\n" + respHeader);
|
||||
Assert.assertThat("Content-Encoding should be gzipped",respHeader,containsString("Content-Encoding: gzip\r\n"));
|
||||
Assert.assertThat("Transfer-Encoding should be chunked",respHeader,containsString("Transfer-Encoding: chunked\r\n"));
|
||||
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");
|
||||
|
@ -118,7 +149,7 @@ public class GzipWithPipeliningTest
|
|||
|
||||
// Read only 20% - intentionally a partial read.
|
||||
System.out.println("Attempting to read partial content ...");
|
||||
int readBytes = client.readBody(rawOutputStream,(int)((float)chunkSize * 0.20f));
|
||||
int readBytes = client.readBody(rawOutputStream,(int)(chunkSize * 0.20f));
|
||||
System.out.printf("Read %,d bytes%n",readBytes);
|
||||
|
||||
// Issue another request
|
||||
|
@ -133,14 +164,14 @@ public class GzipWithPipeliningTest
|
|||
readBytes = client.readBody(rawOutputStream,(int)chunkSize);
|
||||
System.out.printf("Read %,d bytes%n",readBytes);
|
||||
line = client.readLine();
|
||||
Assert.assertThat("Chunk delim should be an empty line with CR+LF",line,is(""));
|
||||
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();
|
||||
Assert.assertThat("Inter-pipeline delim should be an empty line with CR+LF",line,is(""));
|
||||
assertThat("Inter-pipeline delim should be an empty line with CR+LF",line,is(""));
|
||||
|
||||
// Sha1tracking for 1st Request
|
||||
MessageDigest digestTxt = MessageDigest.getInstance("SHA1");
|
||||
|
@ -149,14 +180,23 @@ public class GzipWithPipeliningTest
|
|||
// Decompress 1st request and calculate sha1sum
|
||||
IO.close(rawOutputStream);
|
||||
FileInputStream rawInputStream = new FileInputStream(rawOutputFile);
|
||||
GZIPInputStream ungzipStream = new GZIPInputStream(rawInputStream);
|
||||
IO.copy(ungzipStream, digesterTxt);
|
||||
InputStream uncompressedStream = null;
|
||||
if (GzipFilter.DEFLATE.equals(encodingHeader))
|
||||
{
|
||||
uncompressedStream = new InflaterInputStream(rawInputStream);
|
||||
}
|
||||
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);
|
||||
Assert.assertThat("Content-Encoding should NOT be gzipped",respHeader,not(containsString("Content-Encoding: gzip\r\n")));
|
||||
Assert.assertThat("Transfer-Encoding should NOT be chunked",respHeader,not(containsString("Transfer-Encoding: chunked\r\n")));
|
||||
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");
|
||||
|
@ -164,7 +204,7 @@ public class GzipWithPipeliningTest
|
|||
|
||||
// Read 2nd request body
|
||||
int contentLength = client.getContentLength(respHeader);
|
||||
Assert.assertThat("Image Content Length",(long)contentLength,is(pngFile.length()));
|
||||
assertThat("Image Content Length",(long)contentLength,is(pngFile.length()));
|
||||
client.readBody(digesterImg,contentLength);
|
||||
|
||||
// Validate checksums
|
||||
|
@ -183,7 +223,7 @@ public class GzipWithPipeliningTest
|
|||
{
|
||||
String expectedSha1 = loadSha1sum(testResourceFile + ".sha1");
|
||||
String actualSha1 = Hex.asHex(digest.digest());
|
||||
Assert.assertEquals(testResourceFile + " / SHA1Sum of content",expectedSha1,actualSha1);
|
||||
assertEquals(testResourceFile + " / SHA1Sum of content",expectedSha1,actualSha1);
|
||||
}
|
||||
|
||||
private String loadSha1sum(String testResourceSha1Sum) throws IOException
|
||||
|
@ -192,7 +232,7 @@ public class GzipWithPipeliningTest
|
|||
String contents = IO.readToString(sha1File);
|
||||
Pattern pat = Pattern.compile("^[0-9A-Fa-f]*");
|
||||
Matcher mat = pat.matcher(contents);
|
||||
Assert.assertTrue("Should have found HEX code in SHA1 file: " + sha1File,mat.find());
|
||||
assertTrue("Should have found HEX code in SHA1 file: " + sha1File,mat.find());
|
||||
return mat.group();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
|
||||
package org.eclipse.jetty.servlets;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.servlet.Servlet;
|
||||
|
||||
import org.eclipse.jetty.servlet.FilterHolder;
|
||||
|
@ -21,6 +24,9 @@ import org.eclipse.jetty.servlets.gzip.TestMinGzipSizeServlet;
|
|||
import org.eclipse.jetty.toolchain.test.TestingDir;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
/**
|
||||
* Perform specific tests on the IncludableGzipFilter's ability to manage
|
||||
|
@ -28,17 +34,36 @@ import org.junit.Test;
|
|||
*
|
||||
* @see <a href="Eclipse Bug 366106">http://bugs.eclipse.org/366106</a>
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class IncludableGzipFilterMinSizeTest
|
||||
{
|
||||
@Parameters
|
||||
public static Collection<String[]> data()
|
||||
{
|
||||
String[][] data = new String[][]
|
||||
{
|
||||
{ GzipFilter.GZIP },
|
||||
{ GzipFilter.DEFLATE }
|
||||
};
|
||||
|
||||
return Arrays.asList(data);
|
||||
}
|
||||
|
||||
public IncludableGzipFilterMinSizeTest(String compressionType)
|
||||
{
|
||||
this.compressionType = compressionType;
|
||||
}
|
||||
|
||||
@Rule
|
||||
public TestingDir testdir = new TestingDir();
|
||||
|
||||
private String compressionType;
|
||||
private Class<? extends Servlet> testServlet = TestMinGzipSizeServlet.class;
|
||||
|
||||
@Test
|
||||
public void testUnderMinSize() throws Exception
|
||||
{
|
||||
GzipTester tester = new GzipTester(testdir);
|
||||
GzipTester tester = new GzipTester(testdir, compressionType);
|
||||
// Use IncludableGzipFilter
|
||||
tester.setGzipFilterClass(IncludableGzipFilter.class);
|
||||
|
||||
|
@ -64,7 +89,7 @@ public class IncludableGzipFilterMinSizeTest
|
|||
@Test
|
||||
public void testOverMinSize() throws Exception
|
||||
{
|
||||
GzipTester tester = new GzipTester(testdir);
|
||||
GzipTester tester = new GzipTester(testdir, compressionType);
|
||||
// Use IncludableGzipFilter
|
||||
tester.setGzipFilterClass(IncludableGzipFilter.class);
|
||||
|
||||
|
|
|
@ -22,7 +22,10 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
@ -36,9 +39,28 @@ 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;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class IncludableGzipFilterTest
|
||||
{
|
||||
@Parameters
|
||||
public static Collection<String[]> data()
|
||||
{
|
||||
String[][] data = new String[][]
|
||||
{
|
||||
{ GzipFilter.GZIP },
|
||||
{ GzipFilter.DEFLATE }
|
||||
};
|
||||
|
||||
return Arrays.asList(data);
|
||||
}
|
||||
|
||||
@Rule
|
||||
public TestingDir testdir = new TestingDir();
|
||||
|
||||
private static String __content =
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. In quis felis nunc. "+
|
||||
"Quisque suscipit mauris et ante auctor ornare rhoncus lacus aliquet. Pellentesque "+
|
||||
|
@ -53,11 +75,14 @@ public class IncludableGzipFilterTest
|
|||
"Aliquam purus mauris, consectetur nec convallis lacinia, porta sed ante. Suspendisse "+
|
||||
"et cursus magna. Donec orci enim, molestie a lobortis eu, imperdiet vitae neque.";
|
||||
|
||||
@Rule
|
||||
public TestingDir testdir = new TestingDir();
|
||||
|
||||
private ServletTester tester;
|
||||
|
||||
private String compressionType;
|
||||
|
||||
public IncludableGzipFilterTest(String compressionType)
|
||||
{
|
||||
this.compressionType = compressionType;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
|
@ -95,7 +120,7 @@ public class IncludableGzipFilterTest
|
|||
request.setMethod("GET");
|
||||
request.setVersion("HTTP/1.0");
|
||||
request.setHeader("Host","tester");
|
||||
request.setHeader("accept-encoding","gzip");
|
||||
request.setHeader("accept-encoding", compressionType);
|
||||
request.setURI("/context/file.txt");
|
||||
|
||||
ByteArrayBuffer reqsBuff = new ByteArrayBuffer(request.generate().getBytes());
|
||||
|
@ -103,10 +128,19 @@ public class IncludableGzipFilterTest
|
|||
response.parse(respBuff.asArray());
|
||||
|
||||
assertTrue(response.getMethod()==null);
|
||||
assertTrue(response.getHeader("Content-Encoding").equalsIgnoreCase("gzip"));
|
||||
assertTrue(response.getHeader("Content-Encoding").equalsIgnoreCase(compressionType));
|
||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||
|
||||
InputStream testIn = new GZIPInputStream(new ByteArrayInputStream(response.getContentBytes()));
|
||||
InputStream testIn = null;
|
||||
ByteArrayInputStream compressedResponseStream = new ByteArrayInputStream(response.getContentBytes());
|
||||
if (compressionType.equals(GzipFilter.GZIP))
|
||||
{
|
||||
testIn = new GZIPInputStream(compressedResponseStream);
|
||||
}
|
||||
else if (compressionType.equals(GzipFilter.DEFLATE))
|
||||
{
|
||||
testIn = new InflaterInputStream(compressedResponseStream);
|
||||
}
|
||||
ByteArrayOutputStream testOut = new ByteArrayOutputStream();
|
||||
IO.copy(testIn,testOut);
|
||||
|
||||
|
|
|
@ -25,8 +25,9 @@ public class PipelineHelper
|
|||
private Socket socket;
|
||||
private OutputStream outputStream;
|
||||
private InputStream inputStream;
|
||||
private String encodingHeader;
|
||||
|
||||
public PipelineHelper(URI uri)
|
||||
public PipelineHelper(URI uri, String encodingHeader)
|
||||
{
|
||||
if (LOG instanceof StdErrLog)
|
||||
{
|
||||
|
@ -34,6 +35,7 @@ public class PipelineHelper
|
|||
}
|
||||
this.uri = uri;
|
||||
this.endpoint = new InetSocketAddress(uri.getHost(),uri.getPort());
|
||||
this.encodingHeader = encodingHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,7 +78,7 @@ public class PipelineHelper
|
|||
req.append("Accept-Language: en-us\r\n");
|
||||
if (acceptGzipped)
|
||||
{
|
||||
req.append("Accept-Encoding: gzip, deflate\r\n");
|
||||
req.append("Accept-Encoding: " + encodingHeader + "\r\n");
|
||||
}
|
||||
req.append("Cookie: JSESSIONID=spqx8v8szylt1336t96vc6mw0\r\n");
|
||||
if ( close )
|
||||
|
@ -134,7 +136,7 @@ public class PipelineHelper
|
|||
while (!(foundCR && foundLF))
|
||||
{
|
||||
b = inputStream.read();
|
||||
Assert.assertThat("Should not have hit EOL (yet) during chunk size read",(int)b,not(-1));
|
||||
Assert.assertThat("Should not have hit EOL (yet) during chunk size read",b,not(-1));
|
||||
if (b == 0x0D)
|
||||
{
|
||||
foundCR = true;
|
||||
|
@ -163,7 +165,7 @@ public class PipelineHelper
|
|||
while (!(foundCR && foundLF))
|
||||
{
|
||||
b = inputStream.read();
|
||||
Assert.assertThat("Should not have hit EOL (yet) during chunk size read",(int)b,not(-1));
|
||||
Assert.assertThat("Should not have hit EOL (yet) during chunk size read",b,not(-1));
|
||||
if (b == 0x0D)
|
||||
{
|
||||
foundCR = true;
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
package org.eclipse.jetty.servlets.gzip;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
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.assertThat;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
|
@ -12,6 +20,8 @@ import java.util.Enumeration;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
import javax.servlet.Servlet;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
@ -26,12 +36,6 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
|||
import org.eclipse.jetty.toolchain.test.TestingDir;
|
||||
import org.junit.Assert;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
||||
public class GzipTester
|
||||
{
|
||||
private Class<? extends GzipFilter> gzipFilterClass = GzipFilter.class;
|
||||
|
@ -39,10 +43,12 @@ public class GzipTester
|
|||
private String userAgent = null;
|
||||
private ServletTester servletTester;
|
||||
private TestingDir testdir;
|
||||
private String compressionType;
|
||||
|
||||
public GzipTester(TestingDir testingdir)
|
||||
public GzipTester(TestingDir testingdir, String compressionType)
|
||||
{
|
||||
this.testdir = testingdir;
|
||||
this.compressionType = compressionType;
|
||||
// Make sure we start with a clean testing directory.
|
||||
// DOES NOT WORK IN WINDOWS - this.testdir.ensureEmpty();
|
||||
}
|
||||
|
@ -61,7 +67,7 @@ public class GzipTester
|
|||
request.setMethod("GET");
|
||||
request.setVersion("HTTP/1.0");
|
||||
request.setHeader("Host","tester");
|
||||
request.setHeader("Accept-Encoding","gzip");
|
||||
request.setHeader("Accept-Encoding",compressionType);
|
||||
if (this.userAgent != null)
|
||||
request.setHeader("User-Agent", this.userAgent);
|
||||
request.setURI("/context/" + requestedFilename);
|
||||
|
@ -76,7 +82,7 @@ public class GzipTester
|
|||
Assert.assertThat("Response.method",response.getMethod(),nullValue());
|
||||
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("gzip"));
|
||||
Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),containsString(compressionType));
|
||||
|
||||
// Assert that the decompressed contents are what we expect.
|
||||
File serverFile = testdir.getFile(serverFilename);
|
||||
|
@ -89,12 +95,19 @@ public class GzipTester
|
|||
try
|
||||
{
|
||||
bais = new ByteArrayInputStream(response.getContentBytes());
|
||||
in = new GZIPInputStream(bais);
|
||||
if (compressionType.equals(GzipFilter.GZIP))
|
||||
{
|
||||
in = new GZIPInputStream(bais);
|
||||
}
|
||||
else if (compressionType.equals(GzipFilter.DEFLATE))
|
||||
{
|
||||
in = new InflaterInputStream(bais);
|
||||
}
|
||||
out = new ByteArrayOutputStream();
|
||||
IO.copy(in,out);
|
||||
|
||||
actual = out.toString(encoding);
|
||||
Assert.assertEquals("Uncompressed contents",expected,actual);
|
||||
assertThat("Uncompressed contents",actual,equalTo(expected));
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -128,7 +141,7 @@ public class GzipTester
|
|||
request.setMethod("GET");
|
||||
request.setVersion("HTTP/1.0");
|
||||
request.setHeader("Host","tester");
|
||||
request.setHeader("Accept-Encoding","gzip");
|
||||
request.setHeader("Accept-Encoding",compressionType);
|
||||
if (this.userAgent != null)
|
||||
request.setHeader("User-Agent", this.userAgent);
|
||||
request.setURI("/context/" + requestedFilename);
|
||||
|
@ -215,7 +228,7 @@ public class GzipTester
|
|||
request.setMethod("GET");
|
||||
request.setVersion("HTTP/1.0");
|
||||
request.setHeader("Host","tester");
|
||||
request.setHeader("Accept-Encoding","gzip");
|
||||
request.setHeader("Accept-Encoding",compressionType);
|
||||
if (this.userAgent != null)
|
||||
request.setHeader("User-Agent", this.userAgent);
|
||||
if (filename == null)
|
||||
|
@ -238,7 +251,7 @@ public class GzipTester
|
|||
int serverLength = Integer.parseInt(response.getHeader("Content-Length"));
|
||||
Assert.assertThat("Response.header[Content-Length]",serverLength,is(expectedFilesize));
|
||||
}
|
||||
Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),not(containsString("gzip")));
|
||||
Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),not(containsString(compressionType)));
|
||||
|
||||
// Assert that the contents are what we expect.
|
||||
if (filename != null)
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -13,6 +12,14 @@
|
|||
<packaging>pom</packaging>
|
||||
<name>Jetty :: SPDY :: Parent</name>
|
||||
|
||||
<properties>
|
||||
<!--
|
||||
npn version only needs to change when there are changes in that binary, not
|
||||
with each and every release.
|
||||
-->
|
||||
<npn.version>7.6.2.v20120308</npn.version>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>spdy-core</module>
|
||||
<module>spdy-jetty</module>
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty.spdy</groupId>
|
||||
<artifactId>spdy-parent</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -35,6 +35,4 @@ public interface ISession extends Session
|
|||
public <C> void control(IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Handler<C> handler, C context);
|
||||
|
||||
public <C> void data(IStream stream, DataInfo dataInfo, long timeout, TimeUnit unit, Handler<C> handler, C context);
|
||||
|
||||
public int getWindowSize();
|
||||
}
|
||||
|
|
|
@ -80,7 +80,9 @@ public class Promise<T> implements Handler<T>, Future<T>
|
|||
@Override
|
||||
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
|
||||
{
|
||||
latch.await(timeout, unit);
|
||||
boolean elapsed = !latch.await(timeout, unit);
|
||||
if (elapsed)
|
||||
throw new TimeoutException();
|
||||
return result();
|
||||
}
|
||||
|
||||
|
|
|
@ -18,10 +18,10 @@ package org.eclipse.jetty.spdy;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.InterruptedByTimeoutException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Deque;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
@ -78,7 +78,7 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
|
|||
|
||||
private final List<Listener> listeners = new CopyOnWriteArrayList<>();
|
||||
private final ConcurrentMap<Integer, IStream> streams = new ConcurrentHashMap<>();
|
||||
private final Deque<FrameBytes> queue = new LinkedList<>();
|
||||
private final LinkedList<FrameBytes> queue = new LinkedList<>();
|
||||
private final ByteBufferPool bufferPool;
|
||||
private final Executor threadPool;
|
||||
private final ScheduledExecutorService scheduler;
|
||||
|
@ -253,9 +253,9 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<Stream> getStreams()
|
||||
public Set<Stream> getStreams()
|
||||
{
|
||||
List<Stream> result = new ArrayList<>();
|
||||
Set<Stream> result = new HashSet<>();
|
||||
result.addAll(streams.values());
|
||||
return result;
|
||||
}
|
||||
|
@ -540,7 +540,10 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
|
|||
Settings.Setting windowSizeSetting = frame.getSettings().get(Settings.ID.INITIAL_WINDOW_SIZE);
|
||||
if (windowSizeSetting != null)
|
||||
{
|
||||
int prevWindowSize = windowSize;
|
||||
windowSize = windowSizeSetting.value();
|
||||
for (IStream stream : streams.values())
|
||||
stream.updateWindowSize(windowSize - prevWindowSize);
|
||||
logger.debug("Updated window size to {}", windowSize);
|
||||
}
|
||||
|
||||
|
@ -728,10 +731,10 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
|
|||
{
|
||||
ByteBuffer buffer = generator.control(frame);
|
||||
logger.debug("Queuing {} on {}", frame, stream);
|
||||
ControlFrameBytes<C> frameBytes = new ControlFrameBytes<>(handler, context, frame, buffer);
|
||||
ControlFrameBytes<C> frameBytes = new ControlFrameBytes<>(stream, handler, context, frame, buffer);
|
||||
if (timeout > 0)
|
||||
frameBytes.task = scheduler.schedule(frameBytes, timeout, unit);
|
||||
enqueueLast(frameBytes);
|
||||
append(frameBytes);
|
||||
}
|
||||
|
||||
flush();
|
||||
|
@ -762,10 +765,10 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
|
|||
public <C> void data(IStream stream, DataInfo dataInfo, long timeout, TimeUnit unit, Handler<C> handler, C context)
|
||||
{
|
||||
logger.debug("Queuing {} on {}", dataInfo, stream);
|
||||
DataFrameBytes<C> frameBytes = new DataFrameBytes<>(handler, context, stream, dataInfo);
|
||||
DataFrameBytes<C> frameBytes = new DataFrameBytes<>(stream, handler, context, dataInfo);
|
||||
if (timeout > 0)
|
||||
frameBytes.task = scheduler.schedule(frameBytes, timeout, unit);
|
||||
enqueueLast(frameBytes);
|
||||
append(frameBytes);
|
||||
flush();
|
||||
}
|
||||
|
||||
|
@ -774,56 +777,71 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
|
|||
threadPool.execute(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWindowSize()
|
||||
{
|
||||
return windowSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush()
|
||||
{
|
||||
FrameBytes frameBytes;
|
||||
ByteBuffer buffer;
|
||||
FrameBytes frameBytes = null;
|
||||
ByteBuffer buffer = null;
|
||||
synchronized (queue)
|
||||
{
|
||||
if (flushing)
|
||||
if (flushing || queue.isEmpty())
|
||||
return;
|
||||
|
||||
frameBytes = queue.poll();
|
||||
if (frameBytes == null)
|
||||
return;
|
||||
|
||||
buffer = frameBytes.getByteBuffer();
|
||||
if (buffer == null)
|
||||
Set<IStream> stalledStreams = null;
|
||||
for (int i = 0; i < queue.size(); ++i)
|
||||
{
|
||||
enqueueFirst(frameBytes);
|
||||
logger.debug("Flush skipped, {} frame(s) in queue", queue.size());
|
||||
return;
|
||||
frameBytes = queue.get(i);
|
||||
|
||||
if (stalledStreams != null && stalledStreams.contains(frameBytes.getStream()))
|
||||
continue;
|
||||
|
||||
buffer = frameBytes.getByteBuffer();
|
||||
if (buffer != null)
|
||||
{
|
||||
queue.remove(i);
|
||||
break;
|
||||
}
|
||||
|
||||
if (stalledStreams == null)
|
||||
stalledStreams = new HashSet<>();
|
||||
stalledStreams.add(frameBytes.getStream());
|
||||
|
||||
logger.debug("Flush stalled for {}, {} frame(s) in queue", frameBytes, queue.size());
|
||||
}
|
||||
|
||||
if (buffer == null)
|
||||
return;
|
||||
|
||||
flushing = true;
|
||||
logger.debug("Flushing {}, {} frame(s) in queue", frameBytes, queue.size());
|
||||
}
|
||||
|
||||
logger.debug("Writing {} frame bytes of {}", buffer.remaining(), frameBytes);
|
||||
write(buffer, this, frameBytes);
|
||||
}
|
||||
|
||||
private void enqueueLast(FrameBytes frameBytes)
|
||||
private void append(FrameBytes frameBytes)
|
||||
{
|
||||
// TODO: handle priority; e.g. use queues to prioritize the buffers ?
|
||||
synchronized (queue)
|
||||
{
|
||||
queue.offerLast(frameBytes);
|
||||
}
|
||||
enqueue(frameBytes, false);
|
||||
}
|
||||
|
||||
private void enqueueFirst(FrameBytes frameBytes)
|
||||
private void prepend(FrameBytes frameBytes)
|
||||
{
|
||||
enqueue(frameBytes, true);
|
||||
}
|
||||
|
||||
private void enqueue(FrameBytes frameBytes, boolean prepend)
|
||||
{
|
||||
synchronized (queue)
|
||||
{
|
||||
queue.offerFirst(frameBytes);
|
||||
int index = 0;
|
||||
while (index < queue.size())
|
||||
{
|
||||
FrameBytes element = queue.get(index);
|
||||
int comparison = element.compareTo(frameBytes);
|
||||
if (comparison > 0 || prepend && comparison == 0)
|
||||
break;
|
||||
++index;
|
||||
}
|
||||
queue.add(index, frameBytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -836,6 +854,7 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
|
|||
flushing = false;
|
||||
}
|
||||
frameBytes.complete();
|
||||
flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -847,7 +866,10 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
|
|||
protected void write(ByteBuffer buffer, Handler<FrameBytes> handler, FrameBytes frameBytes)
|
||||
{
|
||||
if (controller != null)
|
||||
{
|
||||
logger.debug("Writing {} frame bytes of {}", buffer.remaining(), frameBytes);
|
||||
controller.write(buffer, handler, frameBytes);
|
||||
}
|
||||
}
|
||||
|
||||
private <C> void complete(final Handler<C> handler, final C context)
|
||||
|
@ -913,8 +935,10 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
|
|||
}
|
||||
}
|
||||
|
||||
public interface FrameBytes
|
||||
public interface FrameBytes extends Comparable<FrameBytes>
|
||||
{
|
||||
public IStream getStream();
|
||||
|
||||
public abstract ByteBuffer getByteBuffer();
|
||||
|
||||
public abstract void complete();
|
||||
|
@ -922,16 +946,30 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
|
|||
|
||||
private abstract class AbstractFrameBytes<C> implements FrameBytes, Runnable
|
||||
{
|
||||
private final IStream stream;
|
||||
private final Handler<C> handler;
|
||||
private final C context;
|
||||
protected volatile ScheduledFuture<?> task;
|
||||
|
||||
protected AbstractFrameBytes(Handler<C> handler, C context)
|
||||
protected AbstractFrameBytes(IStream stream, Handler<C> handler, C context)
|
||||
{
|
||||
this.stream = stream;
|
||||
this.handler = handler;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStream getStream()
|
||||
{
|
||||
return stream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(FrameBytes that)
|
||||
{
|
||||
return getStream().getPriority() - that.getStream().getPriority();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void complete()
|
||||
{
|
||||
|
@ -959,9 +997,9 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
|
|||
private final ControlFrame frame;
|
||||
private final ByteBuffer buffer;
|
||||
|
||||
private ControlFrameBytes(Handler<C> handler, C context, ControlFrame frame, ByteBuffer buffer)
|
||||
private ControlFrameBytes(IStream stream, Handler<C> handler, C context, ControlFrame frame, ByteBuffer buffer)
|
||||
{
|
||||
super(handler, context);
|
||||
super(stream, handler, context);
|
||||
this.frame = frame;
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
@ -996,15 +1034,13 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
|
|||
|
||||
private class DataFrameBytes<C> extends AbstractFrameBytes<C>
|
||||
{
|
||||
private final IStream stream;
|
||||
private final DataInfo dataInfo;
|
||||
private int length;
|
||||
private ByteBuffer buffer;
|
||||
private int size;
|
||||
private volatile ByteBuffer buffer;
|
||||
|
||||
private DataFrameBytes(Handler<C> handler, C context, IStream stream, DataInfo dataInfo)
|
||||
private DataFrameBytes(IStream stream, Handler<C> handler, C context, DataInfo dataInfo)
|
||||
{
|
||||
super(handler, context);
|
||||
this.stream = stream;
|
||||
super(stream, handler, context);
|
||||
this.dataInfo = dataInfo;
|
||||
}
|
||||
|
||||
|
@ -1013,15 +1049,16 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
|
|||
{
|
||||
try
|
||||
{
|
||||
IStream stream = getStream();
|
||||
int windowSize = stream.getWindowSize();
|
||||
if (windowSize <= 0)
|
||||
return null;
|
||||
|
||||
length = dataInfo.length();
|
||||
if (length > windowSize)
|
||||
length = windowSize;
|
||||
size = dataInfo.available();
|
||||
if (size > windowSize)
|
||||
size = windowSize;
|
||||
|
||||
buffer = generator.data(stream.getId(), length, dataInfo);
|
||||
buffer = generator.data(stream.getId(), size, dataInfo);
|
||||
return buffer;
|
||||
}
|
||||
catch (Throwable x)
|
||||
|
@ -1034,14 +1071,16 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
|
|||
@Override
|
||||
public void complete()
|
||||
{
|
||||
stream.updateWindowSize(-length);
|
||||
bufferPool.release(buffer);
|
||||
IStream stream = getStream();
|
||||
stream.updateWindowSize(-size);
|
||||
|
||||
if (dataInfo.available() > 0)
|
||||
{
|
||||
// If we could not write a full data frame, then we need first
|
||||
// to finish it, and then process the others (to avoid data garbling)
|
||||
enqueueFirst(this);
|
||||
// We have written a frame out of this DataInfo, but there is more to write.
|
||||
// We need to keep the correct ordering of frames, to avoid that another
|
||||
// DataInfo for the same stream is written before this one is finished.
|
||||
prepend(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1055,7 +1094,7 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
|
|||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("DATA bytes @%x available=%d consumed=%d on %s", dataInfo.hashCode(), dataInfo.available(), dataInfo.consumed(), stream);
|
||||
return String.format("DATA bytes @%x available=%d consumed=%d on %s", dataInfo.hashCode(), dataInfo.available(), dataInfo.consumed(), getStream());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
package org.eclipse.jetty.spdy.api;
|
||||
|
||||
import java.util.EventListener;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -181,7 +181,7 @@ public interface Session
|
|||
/**
|
||||
* @return the streams currently active in this session
|
||||
*/
|
||||
public List<Stream> getStreams();
|
||||
public Set<Stream> getStreams();
|
||||
|
||||
/**
|
||||
* <p>Super interface for listeners with callbacks that are invoked on specific session events.</p>
|
||||
|
|
|
@ -65,7 +65,7 @@ public class SettingsGenerator extends ControlFrameGenerator
|
|||
case SPDY.V2:
|
||||
{
|
||||
// In v2 the format is 24 bits of ID + 8 bits of flag
|
||||
int idAndFlags = (id << 8) + flags;
|
||||
int idAndFlags = (id << 8) + (flags & 0xFF);
|
||||
// A bug in the Chromium implementation forces v2 to have
|
||||
// the 3 ID bytes little endian, so we swap first and third
|
||||
int result = idAndFlags & 0x00_FF_00_FF;
|
||||
|
|
|
@ -58,6 +58,10 @@ public class GoAwayBodyParser extends ControlFrameBodyParser
|
|||
state = State.STATUS_CODE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -87,6 +91,10 @@ public class GoAwayBodyParser extends ControlFrameBodyParser
|
|||
state = State.STATUS_CODE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -22,7 +22,6 @@ import java.util.concurrent.Executor;
|
|||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.Handler;
|
||||
import org.eclipse.jetty.spdy.api.SPDY;
|
||||
|
@ -94,17 +93,15 @@ public class AsyncTimeoutTest
|
|||
Generator generator = new Generator(new StandardByteBufferPool(), new StandardCompressionFactory.StandardCompressor());
|
||||
Session session = new StandardSession(SPDY.V2, bufferPool, threadPool, scheduler, new TestController(), null, 1, null, generator)
|
||||
{
|
||||
private final AtomicInteger flushes = new AtomicInteger();
|
||||
|
||||
@Override
|
||||
public void flush()
|
||||
protected void write(ByteBuffer buffer, Handler<FrameBytes> handler, FrameBytes frameBytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
int flushes = this.flushes.incrementAndGet();
|
||||
if (flushes == 3)
|
||||
// Wait if we're writing the data frame (control frame's first byte is 0x80)
|
||||
if (buffer.get(0) == 0)
|
||||
unit.sleep(2 * timeout);
|
||||
super.flush();
|
||||
super.write(buffer, handler, frameBytes);
|
||||
}
|
||||
catch (InterruptedException x)
|
||||
{
|
||||
|
|
|
@ -1,19 +1,35 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty.spdy</groupId>
|
||||
<artifactId>spdy-parent</artifactId>
|
||||
<version>7.6.2-SNAPSHOT</version>
|
||||
<version>7.6.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spdy-jetty-http-webapp</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<name>Jetty :: SPDY :: Jetty HTTP Web Application</name>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>config</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!--
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>jetty-maven-plugin</artifactId>
|
||||
|
@ -41,7 +57,7 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
-->
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue