Merge over from jetty 7 master
This commit is contained in:
commit
7c7fc30b90
12
VERSION.txt
12
VERSION.txt
|
@ -1,9 +1,15 @@
|
|||
jetty-8.0.1-SNAPSHOT
|
||||
|
||||
jetty-8.0.0.v20110901 - 01 September 2011
|
||||
+ 352565 cookie httponly flag ignored
|
||||
+ 353073 better warnings
|
||||
+ 353285 ServletSecurity annotation ignored
|
||||
+ 356421 Upgraded websocket to draft 13 support
|
||||
|
||||
jetty-7.5.0.v20110901 - 01 September 2011
|
||||
+ 356421 Upgraded websocket to draft 13 support
|
||||
+ 353073 better warnings
|
||||
|
||||
jetty-7.5.0.RC2 - 30 August 2011
|
||||
+ 293739 Hide stacks in named log testing. Various other minor log cleanups in
|
||||
output.
|
||||
|
@ -73,6 +79,12 @@ jetty-7.5.0.RC0 - 15 August 2011
|
|||
+ 354397 RewriteRegexRule handles special characters in regex group
|
||||
+ 354466 Typo in example config of jetty-plus.xml
|
||||
|
||||
jetty-7.4.5.v20110725 - 25 July 2011
|
||||
+ 347484 / - > ${/} in some paths in grant codebases
|
||||
+ 352133 resolve some 1.5isms
|
||||
+ 352421 HttpURI paths beginning with '.'
|
||||
+ 352786 GzipFilter fails to pass parameters to GzipResponseWrapper
|
||||
|
||||
jetty-7.4.4.v20110707 - 07 July 2011
|
||||
+ 308851 Converted all jetty-client module tests to JUnit 4
|
||||
+ 345268 JDBCSessionManager does not work with maxInactiveInterval = -1
|
||||
|
|
|
@ -336,7 +336,9 @@ public class HttpFields
|
|||
{
|
||||
if (__cache.size()>__cacheSize)
|
||||
__cache.clear();
|
||||
__cache.putIfAbsent(value,buffer);
|
||||
Buffer b=__cache.putIfAbsent(value,buffer);
|
||||
if (b!=null)
|
||||
buffer=b;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
|
|
|
@ -35,8 +35,8 @@ import org.eclipse.jetty.util.StringUtil;
|
|||
*/
|
||||
public class GzipResponseWrapper extends HttpServletResponseWrapper
|
||||
{
|
||||
public static int DEFAULT_BUFFER_SIZE = 8192;
|
||||
public static int DEFAULT_MIN_GZIP_SIZE = 256;
|
||||
public static final int DEFAULT_BUFFER_SIZE = 8192;
|
||||
public static final int DEFAULT_MIN_GZIP_SIZE = 256;
|
||||
|
||||
private HttpServletRequest _request;
|
||||
private Set<String> _mimeTypes;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
package org.eclipse.jetty.http.security;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
|
@ -209,7 +210,7 @@ public class Constraint implements Cloneable, Serializable
|
|||
{
|
||||
return "SC{" + _name
|
||||
+ ","
|
||||
+ (_anyRole ? "*" : (_roles == null ? "-" : _roles.toString()))
|
||||
+ (_anyRole ? "*" : (_roles == null ? "-" : Arrays.asList(_roles).toString()))
|
||||
+ ","
|
||||
+ (_dataConstraint == DC_UNSET ? "DC_UNSET}" : (_dataConstraint == DC_NONE ? "NONE}" : (_dataConstraint == DC_INTEGRAL ? "INTEGRAL}" : "CONFIDENTIAL}")));
|
||||
}
|
||||
|
|
|
@ -152,12 +152,22 @@ public class Password extends Credential
|
|||
{
|
||||
case 1:
|
||||
buf.append('0');
|
||||
buf.append('0');
|
||||
buf.append('0');
|
||||
buf.append(x);
|
||||
break;
|
||||
case 2:
|
||||
buf.append('0');
|
||||
buf.append('0');
|
||||
buf.append(x);
|
||||
break;
|
||||
case 3:
|
||||
buf.append('0');
|
||||
buf.append(x);
|
||||
break;
|
||||
default:
|
||||
buf.append(x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
|
|
|
@ -387,7 +387,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
|||
|
||||
private final ConcurrentLinkedQueue<Object> _changes = new ConcurrentLinkedQueue<Object>();
|
||||
|
||||
private Selector _selector;
|
||||
private volatile Selector _selector;
|
||||
|
||||
private volatile Thread _selecting;
|
||||
private int _jvmBug;
|
||||
|
@ -975,7 +975,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
|||
// close endpoints and selector
|
||||
synchronized (this)
|
||||
{
|
||||
for (SelectionKey key:_selector.keys())
|
||||
Selector selector=_selector;
|
||||
for (SelectionKey key:selector.keys())
|
||||
{
|
||||
if (key==null)
|
||||
continue;
|
||||
|
@ -998,8 +999,9 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
|||
_timeout.cancelAll();
|
||||
try
|
||||
{
|
||||
if (_selector != null)
|
||||
_selector.close();
|
||||
selector=_selector;
|
||||
if (selector != null)
|
||||
selector.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
|
|
@ -300,7 +300,12 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
|||
}
|
||||
}
|
||||
}
|
||||
catch (Exception x)
|
||||
catch (ThreadDeath x)
|
||||
{
|
||||
super.close();
|
||||
throw x;
|
||||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
LOG.debug(x);
|
||||
super.close();
|
||||
|
@ -444,8 +449,11 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
|||
case BUFFER_OVERFLOW:
|
||||
case BUFFER_UNDERFLOW:
|
||||
LOG.warn("wrap {}",_result);
|
||||
_closing=true;
|
||||
break;
|
||||
case CLOSED:
|
||||
_closing=true;
|
||||
break;
|
||||
}
|
||||
|
||||
_outNIOBuffer.setPutIndex(put+_result.bytesProduced());
|
||||
|
@ -500,7 +508,7 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
|||
public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
|
||||
{
|
||||
int consumed=0;
|
||||
int available=header.length();
|
||||
int available=header==null?0:header.length();
|
||||
if (buffer!=null)
|
||||
available+=buffer.length();
|
||||
|
||||
|
@ -599,8 +607,11 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
|||
case BUFFER_OVERFLOW:
|
||||
case BUFFER_UNDERFLOW:
|
||||
LOG.warn("unwrap {}",_result);
|
||||
_closing=true;
|
||||
break;
|
||||
case CLOSED:
|
||||
_closing=true;
|
||||
break;
|
||||
}
|
||||
_outNIOBuffer.setPutIndex(put+_result.bytesProduced());
|
||||
}
|
||||
|
@ -895,6 +906,8 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
|||
case BUFFER_OVERFLOW:
|
||||
case BUFFER_UNDERFLOW:
|
||||
LOG.warn("unwrap {}",_result);
|
||||
_closing=true;
|
||||
return _result.bytesConsumed()>0?_result.bytesConsumed():-1;
|
||||
|
||||
case OK:
|
||||
return _result.bytesConsumed();
|
||||
|
@ -965,6 +978,8 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
|||
case BUFFER_OVERFLOW:
|
||||
case BUFFER_UNDERFLOW:
|
||||
LOG.warn("unwrap {}",_result);
|
||||
_closing=true;
|
||||
return _result.bytesConsumed()>0?_result.bytesConsumed():-1;
|
||||
|
||||
case OK:
|
||||
return _result.bytesConsumed();
|
||||
|
|
|
@ -42,33 +42,4 @@ public class IOTest
|
|||
out.toString(),
|
||||
"The quick brown fox jumped over the lazy dog");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringSpeed()
|
||||
{
|
||||
String s="012345678901234567890000000000000000000000000";
|
||||
char[] ca = new char[s.length()];
|
||||
int loops=1000000;
|
||||
|
||||
long start=System.currentTimeMillis();
|
||||
long result=0;
|
||||
for (int loop=0;loop<loops;loop++)
|
||||
{
|
||||
for (int c=s.length();c-->0;)
|
||||
result+=s.charAt(c);
|
||||
}
|
||||
long end=System.currentTimeMillis();
|
||||
System.err.println("charAt "+(end-start)+" "+result);
|
||||
|
||||
start=System.currentTimeMillis();
|
||||
result=0;
|
||||
for (int loop=0;loop<loops;loop++)
|
||||
{
|
||||
s.getChars(0, s.length(), ca, 0);
|
||||
for (int c=s.length();c-->0;)
|
||||
result+=ca[c];
|
||||
}
|
||||
end=System.currentTimeMillis();
|
||||
System.err.println("getChars "+(end-start)+" "+result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,6 +124,12 @@
|
|||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-websocket</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
|
|
|
@ -52,7 +52,7 @@ public class MongoTestServer extends AbstractTestServer
|
|||
_saveAllAttributes = saveAllAttributes;
|
||||
}
|
||||
|
||||
public SessionIdManager newSessionIdManager()
|
||||
public SessionIdManager newSessionIdManager(String config)
|
||||
{
|
||||
if ( _idManager != null )
|
||||
{
|
||||
|
|
|
@ -73,17 +73,14 @@ public class PolicyMonitorTest
|
|||
monitor.setScanInterval(1);
|
||||
|
||||
monitor.start();
|
||||
|
||||
while (! monitor.isInitialized() )
|
||||
{
|
||||
Thread.sleep(100);
|
||||
}
|
||||
monitor.waitForScan();
|
||||
monitor.waitForScan();
|
||||
|
||||
File permFile =new File(MavenTestingUtils.getTargetDir(),
|
||||
"test-classes/monitor-test-2/global-all-permission.policy");
|
||||
|
||||
// Wait so that time is definitely different
|
||||
Thread.sleep(10);
|
||||
// Wait so that time is definitely different
|
||||
monitor.waitForScan();
|
||||
permFile.setLastModified(System.currentTimeMillis());
|
||||
|
||||
monitor.waitForScan();
|
||||
|
|
|
@ -115,6 +115,7 @@ public class DigestAuthenticator extends LoginAuthenticator
|
|||
break;
|
||||
case ',':
|
||||
name = null;
|
||||
break;
|
||||
case ' ':
|
||||
break;
|
||||
|
||||
|
|
|
@ -704,7 +704,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
|
|||
{
|
||||
HttpSessionEvent event=new HttpSessionEvent(session);
|
||||
for (HttpSessionListener listener : _sessionListeners)
|
||||
listener.sessionCreated(event);
|
||||
listener.sessionDestroyed(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -177,7 +177,7 @@ public class HttpConnectionTest
|
|||
response=connector.getResponses("GET /foo/bar%c0%00 HTTP/1.1\n"+
|
||||
"Host: localhost\n"+
|
||||
"\015\012");
|
||||
checkContains(response,0,"pathInfo=/foo/bar?");
|
||||
checkContains(response,0,"HTTP/1.1 400");
|
||||
|
||||
response=connector.getResponses("GET /bad/utf8%c1 HTTP/1.1\n"+
|
||||
"Host: localhost\n"+
|
||||
|
|
|
@ -148,8 +148,10 @@ public class ServletContextHandler extends ContextHandler
|
|||
protected void doStop() throws Exception
|
||||
{
|
||||
super.doStop();
|
||||
_decorators.clear();
|
||||
_wrapper.setHandler(null);
|
||||
if (_decorators != null)
|
||||
_decorators.clear();
|
||||
if (_wrapper != null)
|
||||
_wrapper.setHandler(null);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.eclipse.jetty.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.IllegalFormatCodePointException;
|
||||
|
||||
public abstract class Utf8Appendable
|
||||
{
|
||||
|
@ -69,6 +70,7 @@ public abstract class Utf8Appendable
|
|||
_appendable.append('?');
|
||||
_more=0;
|
||||
_bits=0;
|
||||
throw new NotUtf8Exception();
|
||||
}
|
||||
else
|
||||
_appendable.append((char)(0x7f&b));
|
||||
|
@ -81,6 +83,7 @@ public abstract class Utf8Appendable
|
|||
_appendable.append('?');
|
||||
_more=0;
|
||||
_bits=0;
|
||||
throw new NotUtf8Exception();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -116,7 +119,7 @@ public abstract class Utf8Appendable
|
|||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException("!utf8");
|
||||
throw new NotUtf8Exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,7 +130,7 @@ public abstract class Utf8Appendable
|
|||
_appendable.append('?');
|
||||
_more=0;
|
||||
_bits=0;
|
||||
throw new IllegalArgumentException("!utf8");
|
||||
throw new NotUtf8Exception();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -139,4 +142,12 @@ public abstract class Utf8Appendable
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static class NotUtf8Exception extends IllegalStateException
|
||||
{
|
||||
public NotUtf8Exception()
|
||||
{
|
||||
super("!UTF-8");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -60,7 +60,7 @@ public class Utf8StringBuffer extends Utf8Appendable
|
|||
public StringBuffer getStringBuffer()
|
||||
{
|
||||
if (_more!=0)
|
||||
throw new IllegalStateException("!utf8");
|
||||
throw new NotUtf8Exception();
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ public class Utf8StringBuffer extends Utf8Appendable
|
|||
public String toString()
|
||||
{
|
||||
if (_more!=0)
|
||||
throw new IllegalStateException("!utf8");
|
||||
throw new NotUtf8Exception();
|
||||
return _buffer.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ public class Utf8StringBuilder extends Utf8Appendable
|
|||
public StringBuilder getStringBuilder()
|
||||
{
|
||||
if (_more!=0)
|
||||
throw new IllegalStateException("!utf8");
|
||||
throw new NotUtf8Exception();
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ public class Utf8StringBuilder extends Utf8Appendable
|
|||
public String toString()
|
||||
{
|
||||
if (_more!=0)
|
||||
throw new IllegalStateException("!utf8");
|
||||
throw new NotUtf8Exception();
|
||||
return _buffer.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -166,8 +166,7 @@ public abstract class Resource implements ResourceFactory
|
|||
|
||||
URLConnection connection=url.openConnection();
|
||||
connection.setUseCaches(useCaches);
|
||||
FileResource fileResource= new FileResource(url,connection,file);
|
||||
return fileResource;
|
||||
return new FileResource(url,connection,file);
|
||||
}
|
||||
catch(Exception e2)
|
||||
{
|
||||
|
@ -199,6 +198,18 @@ public abstract class Resource implements ResourceFactory
|
|||
return newResource(url);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public static Resource newResource (File file)
|
||||
throws MalformedURLException, IOException
|
||||
{
|
||||
file = file.getCanonicalFile();
|
||||
URL url = Resource.toURL(file);
|
||||
|
||||
URLConnection connection = url.openConnection();
|
||||
FileResource fileResource = new FileResource(url, connection, file);
|
||||
return fileResource;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Construct a system resource from a string.
|
||||
* The resource is tried as classloader resource before being
|
||||
|
|
|
@ -50,7 +50,7 @@ public class Utf8StringBufferTest
|
|||
}
|
||||
catch(IllegalStateException e)
|
||||
{
|
||||
assertTrue(e.toString().indexOf("!utf8")>=0);
|
||||
assertTrue(e.toString().indexOf("!UTF-8")>=0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,8 +64,16 @@ public class Utf8StringBufferTest
|
|||
bytes[4]=(byte)0x00;
|
||||
|
||||
Utf8StringBuffer buffer = new Utf8StringBuffer();
|
||||
for (int i=0;i<bytes.length;i++)
|
||||
buffer.append(bytes[i]);
|
||||
try
|
||||
{
|
||||
for (int i=0;i<bytes.length;i++)
|
||||
buffer.append(bytes[i]);
|
||||
assertTrue(false);
|
||||
}
|
||||
catch(IllegalStateException e)
|
||||
{
|
||||
assertTrue(e.toString().indexOf("!UTF-8")>=0);
|
||||
}
|
||||
assertEquals("abc?",buffer.toString());
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ public class Utf8StringBuilderTest
|
|||
}
|
||||
catch(IllegalStateException e)
|
||||
{
|
||||
assertTrue(e.toString().indexOf("!utf8")>=0);
|
||||
assertTrue(e.toString().indexOf("!UTF-8")>=0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,9 +64,17 @@ public class Utf8StringBuilderTest
|
|||
bytes[4]=(byte)0x00;
|
||||
|
||||
Utf8StringBuilder buffer = new Utf8StringBuilder();
|
||||
for (int i=0;i<bytes.length;i++)
|
||||
buffer.append(bytes[i]);
|
||||
assertEquals("abc?",buffer.toString());
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < bytes.length; i++)
|
||||
buffer.append(bytes[i]);
|
||||
assertTrue(false);
|
||||
}
|
||||
catch(IllegalStateException e)
|
||||
{
|
||||
assertTrue(e.toString().indexOf("!UTF-8")>=0);
|
||||
}
|
||||
assertEquals("abc?", buffer.toString());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.util.EventListener;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpSessionActivationListener;
|
||||
import javax.servlet.http.HttpSessionAttributeListener;
|
||||
|
@ -99,8 +98,9 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
"org.eclipse.jetty.continuation.", // webapp cannot change continuation classes
|
||||
"org.eclipse.jetty.jndi.", // webapp cannot change naming classes
|
||||
"org.eclipse.jetty.plus.jaas.", // webapp cannot change jaas classes
|
||||
"org.eclipse.jetty.websocket.", // WebSocket is a jetty extension
|
||||
"org.eclipse.jetty.servlet.DefaultServlet" // webapp cannot change default servlets
|
||||
"org.eclipse.jetty.websocket.WebSocket", // WebSocket is a jetty extension
|
||||
"org.eclipse.jetty.websocket.WebSocketFactory", // WebSocket is a jetty extension
|
||||
"org.eclipse.jetty.servlet.DefaultServlet" // webapp cannot change default servlets
|
||||
} ;
|
||||
|
||||
// Server classes are classes that are hidden from being
|
||||
|
@ -112,9 +112,10 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
"-org.eclipse.jetty.continuation.", // don't hide continuation classes
|
||||
"-org.eclipse.jetty.jndi.", // don't hide naming classes
|
||||
"-org.eclipse.jetty.plus.jaas.", // don't hide jaas classes
|
||||
"-org.eclipse.jetty.websocket.", // don't hide websocket extension
|
||||
"-org.eclipse.jetty.websocket.WebSocket", // WebSocket is a jetty extension
|
||||
"-org.eclipse.jetty.websocket.WebSocketFactory", // WebSocket is a jetty extension
|
||||
"-org.eclipse.jetty.servlet.DefaultServlet", // don't hide default servlet
|
||||
"-org.eclipse.jetty.servlet.listener.", //don't hide useful listeners
|
||||
"-org.eclipse.jetty.servlet.listener.", // don't hide useful listeners
|
||||
"org.eclipse.jetty." // hide other jetty classes
|
||||
} ;
|
||||
|
||||
|
|
|
@ -1,77 +1,98 @@
|
|||
|
||||
<?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/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>jetty-project</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>8.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-websocket</artifactId>
|
||||
<name>Jetty :: Websocket</name>
|
||||
<properties>
|
||||
<bundle-symbolic-name>${project.groupId}.websocket</bundle-symbolic-name>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-websocket</artifactId>
|
||||
<name>Jetty :: Websocket</name>
|
||||
|
||||
<properties>
|
||||
<bundle-symbolic-name>${project.groupId}.websocket</bundle-symbolic-name>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${servlet.spec.groupId}</groupId>
|
||||
<artifactId>${servlet.spec.artifactId}</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||
<artifactId>jetty-test-helper</artifactId>
|
||||
<scope>test</scope>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-util</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-io</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-http</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>manifest</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>artifact-jar</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-jar</id>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>findbugs-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<onlyAnalyze>org.eclipse.jetty.websocket.*</onlyAnalyze>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>manifest</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>artifact-jar</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-jar</id>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>findbugs-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<onlyAnalyze>org.eclipse.jetty.websocket.*</onlyAnalyze>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
@ -11,6 +11,9 @@ import org.eclipse.jetty.io.ByteArrayBuffer;
|
|||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
/**
|
||||
* @TODO Implement proposed deflate frame draft
|
||||
*/
|
||||
public class DeflateFrameExtension extends AbstractExtension
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(DeflateFrameExtension.class);
|
||||
|
@ -113,10 +116,10 @@ public class DeflateFrameExtension extends AbstractExtension
|
|||
if (length>0xffff)
|
||||
{
|
||||
out[out_offset++]=0x7f;
|
||||
out[out_offset++]=(byte)((length>>56)&0x7f);
|
||||
out[out_offset++]=(byte)((length>>48)&0xff);
|
||||
out[out_offset++]=(byte)((length>>40)&0xff);
|
||||
out[out_offset++]=(byte)((length>>32)&0xff);
|
||||
out[out_offset++]=(byte)0;
|
||||
out[out_offset++]=(byte)0;
|
||||
out[out_offset++]=(byte)0;
|
||||
out[out_offset++]=(byte)0;
|
||||
out[out_offset++]=(byte)((length>>24)&0xff);
|
||||
out[out_offset++]=(byte)((length>>16)&0xff);
|
||||
out[out_offset++]=(byte)((length>>8)&0xff);
|
||||
|
@ -125,7 +128,7 @@ public class DeflateFrameExtension extends AbstractExtension
|
|||
else if (length >=0x7e)
|
||||
{
|
||||
out[out_offset++]=0x7e;
|
||||
out[out_offset++]=(byte)(byte)(length>>8);
|
||||
out[out_offset++]=(byte)(length>>8);
|
||||
out[out_offset++]=(byte)(length&0xff);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -3,22 +3,23 @@ package org.eclipse.jetty.websocket;
|
|||
|
||||
public class FixedMaskGen implements MaskGen
|
||||
{
|
||||
final byte[] _mask;
|
||||
private final byte[] _mask;
|
||||
|
||||
public FixedMaskGen()
|
||||
{
|
||||
_mask=new byte[]{(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff};
|
||||
this(new byte[]{(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff});
|
||||
}
|
||||
|
||||
public FixedMaskGen(byte[] mask)
|
||||
{
|
||||
_mask=mask;
|
||||
_mask=new byte[4];
|
||||
// Copy to avoid that external code keeps a reference
|
||||
// to the array parameter to modify masking on-the-fly
|
||||
System.arraycopy(mask, 0, _mask, 0, 4);
|
||||
}
|
||||
|
||||
public void genMask(byte[] mask)
|
||||
{
|
||||
mask[0]=_mask[0];
|
||||
mask[1]=_mask[1];
|
||||
mask[2]=_mask[2];
|
||||
mask[3]=_mask[3];
|
||||
System.arraycopy(_mask, 0, mask, 0, 4);
|
||||
}
|
||||
}
|
|
@ -5,10 +5,11 @@ import java.util.Random;
|
|||
|
||||
public class RandomMaskGen implements MaskGen
|
||||
{
|
||||
final Random _random;
|
||||
private final Random _random;
|
||||
|
||||
public RandomMaskGen()
|
||||
{
|
||||
_random=new Random();
|
||||
this(new Random());
|
||||
}
|
||||
|
||||
public RandomMaskGen(Random random)
|
||||
|
@ -18,6 +19,9 @@ public class RandomMaskGen implements MaskGen
|
|||
|
||||
public void genMask(byte[] mask)
|
||||
{
|
||||
// The assumption is that this code is always called
|
||||
// with an external lock held to prevent concurrent access
|
||||
// Otherwise we need to synchronize on the _random.
|
||||
_random.nextBytes(mask);
|
||||
}
|
||||
}
|
|
@ -31,12 +31,11 @@ public class WebSocketBuffers
|
|||
{
|
||||
final private int _bufferSize;
|
||||
final private Buffers _buffers;
|
||||
final private int _maxBuffers=-1;
|
||||
|
||||
public WebSocketBuffers(final int bufferSize)
|
||||
{
|
||||
_bufferSize=bufferSize;
|
||||
_buffers = BuffersFactory.newBuffers(Type.DIRECT,bufferSize,Type.INDIRECT,bufferSize,Type.INDIRECT,_maxBuffers);
|
||||
_buffers = BuffersFactory.newBuffers(Type.DIRECT,bufferSize,Type.INDIRECT,bufferSize,Type.INDIRECT,-1);
|
||||
}
|
||||
|
||||
public Buffer getBuffer()
|
||||
|
|
|
@ -262,7 +262,7 @@ public class WebSocketClient
|
|||
/**
|
||||
* Set the initial maximum binary message size for a connection. This can be changed by
|
||||
* the application calling {@link WebSocket.Connection#setMaxBinaryMessageSize(int)}.
|
||||
* @param maxTextMessageSize The default maximum binary message size (in bytes) for a connection
|
||||
* @param maxBinaryMessageSize The default maximum binary message size (in bytes) for a connection
|
||||
*/
|
||||
public void setMaxBinaryMessageSize(int maxBinaryMessageSize)
|
||||
{
|
||||
|
@ -382,19 +382,20 @@ public class WebSocketClient
|
|||
connection.getConnection().setMaxTextMessageSize(_maxTextMessageSize);
|
||||
connection.getConnection().setMaxBinaryMessageSize(_maxBinaryMessageSize);
|
||||
|
||||
WebSocketConnection con;
|
||||
synchronized (this)
|
||||
{
|
||||
if (_channel!=null)
|
||||
_connection=connection;
|
||||
con=_connection;
|
||||
}
|
||||
|
||||
if (_connection!=null)
|
||||
if (con!=null)
|
||||
{
|
||||
if (_websocket instanceof WebSocket.OnFrame)
|
||||
((WebSocket.OnFrame)_websocket).onHandshake((WebSocket.FrameConnection)connection.getConnection());
|
||||
|
||||
_websocket.onOpen(connection.getConnection());
|
||||
((WebSocket.OnFrame)_websocket).onHandshake((WebSocket.FrameConnection)con.getConnection());
|
||||
|
||||
_websocket.onOpen(con.getConnection());
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
|
|
@ -320,34 +320,41 @@ public class WebSocketClientFactory extends AggregateLifeCycle
|
|||
|
||||
String origin = future.getOrigin();
|
||||
|
||||
String request=
|
||||
"GET "+path+" HTTP/1.1\r\n"+
|
||||
"Host: "+future.getURI().getHost()+":"+_future.getURI().getPort()+"\r\n"+
|
||||
"Upgrade: websocket\r\n"+
|
||||
"Connection: Upgrade\r\n"+
|
||||
"Sec-WebSocket-Key: "+_key+"\r\n"+
|
||||
(origin==null?"":"Origin: "+origin+"\r\n")+
|
||||
"Sec-WebSocket-Version: "+WebSocketConnectionD13.VERSION+"\r\n";
|
||||
StringBuilder request = new StringBuilder(512);
|
||||
request
|
||||
.append("GET ").append(path).append(" HTTP/1.1\r\n")
|
||||
.append("Host: ").append(future.getURI().getHost()).append(":").append(_future.getURI().getPort()).append("\r\n")
|
||||
.append("Upgrade: websocket\r\n")
|
||||
.append("Connection: Upgrade\r\n")
|
||||
.append("Sec-WebSocket-Key: ")
|
||||
.append(_key).append("\r\n");
|
||||
|
||||
if(origin!=null)
|
||||
request.append("Origin: ").append(origin).append("\r\n");
|
||||
|
||||
request.append("Sec-WebSocket-Version: ").append(WebSocketConnectionD13.VERSION).append("\r\n");
|
||||
|
||||
if (future.getProtocol()!=null)
|
||||
request+="Sec-WebSocket-Protocol: "+future.getProtocol()+"\r\n";
|
||||
request.append("Sec-WebSocket-Protocol: ").append(future.getProtocol()).append("\r\n");
|
||||
|
||||
if (future.getCookies()!=null && future.getCookies().size()>0)
|
||||
{
|
||||
for (String cookie : future.getCookies().keySet())
|
||||
request+="Cookie: "+QuotedStringTokenizer.quoteIfNeeded(cookie,HttpFields.__COOKIE_DELIM)+
|
||||
"="+
|
||||
QuotedStringTokenizer.quoteIfNeeded(future.getCookies().get(cookie),HttpFields.__COOKIE_DELIM)+
|
||||
"\r\n";
|
||||
request
|
||||
.append("Cookie: ")
|
||||
.append(QuotedStringTokenizer.quoteIfNeeded(cookie,HttpFields.__COOKIE_DELIM))
|
||||
.append("=")
|
||||
.append(QuotedStringTokenizer.quoteIfNeeded(future.getCookies().get(cookie),HttpFields.__COOKIE_DELIM))
|
||||
.append("\r\n");
|
||||
}
|
||||
|
||||
request+="\r\n";
|
||||
request.append("\r\n");
|
||||
|
||||
// TODO extensions
|
||||
|
||||
try
|
||||
{
|
||||
Buffer handshake = new ByteArrayBuffer(request,false);
|
||||
Buffer handshake = new ByteArrayBuffer(request.toString(),false);
|
||||
int len=handshake.length();
|
||||
if (len!=_endp.flush(handshake))
|
||||
throw new IOException("incomplete");
|
||||
|
|
|
@ -18,10 +18,10 @@ import java.security.MessageDigest;
|
|||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.HttpURI;
|
||||
import org.eclipse.jetty.io.AbstractConnection;
|
||||
import org.eclipse.jetty.io.AsyncEndPoint;
|
||||
import org.eclipse.jetty.io.Buffer;
|
||||
|
@ -30,8 +30,8 @@ import org.eclipse.jetty.io.Connection;
|
|||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
|
||||
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
|
||||
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.Utf8StringBuilder;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.WebSocket.OnFrame;
|
||||
|
@ -65,7 +65,7 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
|
|||
_protocol=protocol;
|
||||
|
||||
_generator = new WebSocketGeneratorD00(buffers, _endp);
|
||||
_parser = new WebSocketParserD00(buffers, endpoint, new FrameHandlerD0(_websocket));
|
||||
_parser = new WebSocketParserD00(buffers, endpoint, new FrameHandlerD00(_websocket));
|
||||
|
||||
if (_endp instanceof SelectChannelEndPoint)
|
||||
{
|
||||
|
@ -348,11 +348,9 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
|
|||
fodder[5]=(byte)(0xff&(key2>>16));
|
||||
fodder[6]=(byte)(0xff&(key2>>8));
|
||||
fodder[7]=(byte)(0xff&key2);
|
||||
for (int i=0;i<8;i++)
|
||||
fodder[8+i]=key3[i];
|
||||
System.arraycopy(key3, 0, fodder, 8, 8);
|
||||
md.update(fodder);
|
||||
byte[] result=md.digest();
|
||||
return result;
|
||||
return md.digest();
|
||||
}
|
||||
catch (NoSuchAlgorithmException e)
|
||||
{
|
||||
|
@ -371,11 +369,15 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
|
|||
String query=request.getQueryString();
|
||||
if (query!=null && query.length()>0)
|
||||
uri+="?"+query;
|
||||
uri=new HttpURI(uri).toString();
|
||||
String host=request.getHeader("Host");
|
||||
|
||||
String origin=request.getHeader("Sec-WebSocket-Origin");
|
||||
if (origin==null)
|
||||
origin=request.getHeader("Origin");
|
||||
if (origin!=null)
|
||||
origin= QuotedStringTokenizer.quoteIfNeeded(origin, "\r\n");
|
||||
|
||||
|
||||
String key1 = request.getHeader("Sec-WebSocket-Key1");
|
||||
|
||||
|
@ -449,12 +451,11 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
|
|||
return _protocol;
|
||||
}
|
||||
|
||||
class FrameHandlerD0 implements WebSocketParser.FrameHandler
|
||||
static class FrameHandlerD00 implements WebSocketParser.FrameHandler
|
||||
{
|
||||
final WebSocket _websocket;
|
||||
final Utf8StringBuilder _utf8 = new Utf8StringBuilder();
|
||||
|
||||
FrameHandlerD0(WebSocket websocket)
|
||||
FrameHandlerD00(WebSocket websocket)
|
||||
{
|
||||
_websocket=websocket;
|
||||
}
|
||||
|
@ -488,7 +489,6 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
|
|||
|
||||
public void close(int code,String message)
|
||||
{
|
||||
close(code,message);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ import java.io.UnsupportedEncodingException;
|
|||
import java.security.MessageDigest;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
@ -85,8 +84,8 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
|
|||
private final OnTextMessage _onTextMessage;
|
||||
private final OnControl _onControl;
|
||||
private final String _protocol;
|
||||
private boolean _closedIn;
|
||||
private boolean _closedOut;
|
||||
private volatile boolean _closedIn;
|
||||
private volatile boolean _closedOut;
|
||||
private int _maxTextMessageSize;
|
||||
private int _maxBinaryMessageSize=-1;
|
||||
|
||||
|
@ -116,7 +115,6 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
|
|||
{
|
||||
super(endpoint,timestamp);
|
||||
|
||||
// TODO - can we use the endpoint idle mechanism?
|
||||
if (endpoint instanceof AsyncEndPoint)
|
||||
((AsyncEndPoint)endpoint).cancelIdle();
|
||||
|
||||
|
@ -131,7 +129,6 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
|
|||
_parser = new WebSocketParserD06(buffers, endpoint, _frameHandler,true);
|
||||
_protocol=protocol;
|
||||
|
||||
// TODO should these be AsyncEndPoint checks/calls?
|
||||
if (_endp instanceof SelectChannelEndPoint)
|
||||
{
|
||||
final SelectChannelEndPoint scep=(SelectChannelEndPoint)_endp;
|
||||
|
@ -734,10 +731,6 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
|
|||
/* ------------------------------------------------------------ */
|
||||
public void handshake(HttpServletRequest request, HttpServletResponse response, String subprotocol) throws IOException
|
||||
{
|
||||
String uri=request.getRequestURI();
|
||||
String query=request.getQueryString();
|
||||
if (query!=null && query.length()>0)
|
||||
uri+="?"+query;
|
||||
String key = request.getHeader("Sec-WebSocket-Key");
|
||||
|
||||
response.setHeader("Upgrade","WebSocket");
|
||||
|
|
|
@ -18,7 +18,6 @@ import java.io.UnsupportedEncodingException;
|
|||
import java.security.MessageDigest;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
@ -164,7 +163,6 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc
|
|||
|
||||
_protocol=protocol;
|
||||
|
||||
// TODO should these be AsyncEndPoint checks/calls?
|
||||
if (_endp instanceof SelectChannelEndPoint)
|
||||
{
|
||||
final SelectChannelEndPoint scep=(SelectChannelEndPoint)_endp;
|
||||
|
@ -762,7 +760,6 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc
|
|||
else if (_connection.getMaxBinaryMessageSize()>=0)
|
||||
{
|
||||
_opcode=opcode;
|
||||
// TODO use a growing buffer rather than a fixed one.
|
||||
if (_aggregate==null)
|
||||
_aggregate=new ByteArrayBuffer(_connection.getMaxBinaryMessageSize());
|
||||
_aggregate.put(buffer);
|
||||
|
@ -833,13 +830,9 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc
|
|||
/* ------------------------------------------------------------ */
|
||||
public void handshake(HttpServletRequest request, HttpServletResponse response, String subprotocol) throws IOException
|
||||
{
|
||||
String uri=request.getRequestURI();
|
||||
String query=request.getQueryString();
|
||||
if (query!=null && query.length()>0)
|
||||
uri+="?"+query;
|
||||
String key = request.getHeader("Sec-WebSocket-Key");
|
||||
|
||||
response.setHeader("Upgrade","WebSocket");
|
||||
response.setHeader("Upgrade", "WebSocket");
|
||||
response.addHeader("Connection","Upgrade");
|
||||
response.addHeader("Sec-WebSocket-Accept",hashKey(key));
|
||||
if (subprotocol!=null)
|
||||
|
|
|
@ -18,7 +18,6 @@ import java.io.UnsupportedEncodingException;
|
|||
import java.security.MessageDigest;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
@ -31,6 +30,7 @@ import org.eclipse.jetty.io.EndPoint;
|
|||
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
|
||||
import org.eclipse.jetty.util.B64Code;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.Utf8Appendable;
|
||||
import org.eclipse.jetty.util.Utf8StringBuilder;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
@ -84,7 +84,6 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||
private final IdleCheck _idle;
|
||||
private final List<Extension> _extensions;
|
||||
private final WebSocketParserD13 _parser;
|
||||
private final WebSocketParser.FrameHandler _inbound;
|
||||
private final WebSocketGeneratorD13 _generator;
|
||||
private final WebSocketGenerator _outbound;
|
||||
private final WebSocket _webSocket;
|
||||
|
@ -114,8 +113,6 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||
}
|
||||
}
|
||||
|
||||
private final WebSocketParser.FrameHandler _frameHandler= new WSFrameHandler();
|
||||
|
||||
private final WebSocket.FrameConnection _connection = new WSFrameConnection();
|
||||
|
||||
|
||||
|
@ -148,6 +145,7 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||
_generator = new WebSocketGeneratorD13(buffers, _endp,maskgen);
|
||||
|
||||
_extensions=extensions;
|
||||
WebSocketParser.FrameHandler frameHandler = new WSFrameHandler();
|
||||
if (_extensions!=null)
|
||||
{
|
||||
int e=0;
|
||||
|
@ -155,16 +153,16 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||
{
|
||||
extension.bind(
|
||||
_connection,
|
||||
e==extensions.size()-1?_frameHandler:extensions.get(e+1),
|
||||
e==extensions.size()-1? frameHandler :extensions.get(e+1),
|
||||
e==0?_generator:extensions.get(e-1));
|
||||
e++;
|
||||
}
|
||||
}
|
||||
|
||||
_outbound=(_extensions==null||_extensions.size()==0)?_generator:extensions.get(extensions.size()-1);
|
||||
_inbound=(_extensions==null||_extensions.size()==0)?_frameHandler:extensions.get(0);
|
||||
WebSocketParser.FrameHandler inbound = (_extensions == null || _extensions.size() == 0) ? frameHandler : extensions.get(0);
|
||||
|
||||
_parser = new WebSocketParserD13(buffers, endpoint,_inbound,maskgen==null);
|
||||
_parser = new WebSocketParserD13(buffers, endpoint, inbound,maskgen==null);
|
||||
|
||||
_protocol=protocol;
|
||||
|
||||
|
@ -302,14 +300,14 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||
{
|
||||
LOG.debug("ClosedIn {} {}",this,message);
|
||||
|
||||
final boolean closedOut;
|
||||
final boolean closed;
|
||||
final boolean close;
|
||||
final boolean tell_app;
|
||||
synchronized (this)
|
||||
{
|
||||
closedOut=_closedOut;
|
||||
close=_closedOut;
|
||||
_closedIn=true;
|
||||
closed=_closeCode==0;
|
||||
if (closed)
|
||||
tell_app=_closeCode==0;
|
||||
if (tell_app)
|
||||
{
|
||||
_closeCode=code;
|
||||
_closeMessage=message;
|
||||
|
@ -318,14 +316,14 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||
|
||||
try
|
||||
{
|
||||
if (closed)
|
||||
if (tell_app)
|
||||
_webSocket.onClose(code,message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if (closedOut)
|
||||
if (close)
|
||||
_endp.close();
|
||||
else
|
||||
closeOut(code,message);
|
||||
|
@ -343,13 +341,15 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||
LOG.debug("ClosedOut {} {}",this,message);
|
||||
|
||||
final boolean close;
|
||||
final boolean closed;
|
||||
final boolean tell_app;
|
||||
final boolean send_close;
|
||||
synchronized (this)
|
||||
{
|
||||
close=_closedIn || _closedOut;
|
||||
close=_closedIn;
|
||||
send_close=!_closedOut;
|
||||
_closedOut=true;
|
||||
closed=_closeCode==0;
|
||||
if (closed)
|
||||
tell_app=_closeCode==0;
|
||||
if (tell_app)
|
||||
{
|
||||
_closeCode=code;
|
||||
_closeMessage=message;
|
||||
|
@ -358,16 +358,14 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||
|
||||
try
|
||||
{
|
||||
if (closed)
|
||||
if (tell_app)
|
||||
_webSocket.onClose(code,message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if (close)
|
||||
_endp.close();
|
||||
else
|
||||
if (send_close)
|
||||
{
|
||||
if (code<=0)
|
||||
code=WebSocketConnectionD13.CLOSE_NORMAL;
|
||||
|
@ -375,8 +373,12 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||
bytes[0]=(byte)(code/0x100);
|
||||
bytes[1]=(byte)(code%0x100);
|
||||
_outbound.addFrame((byte)FLAG_FIN,WebSocketConnectionD13.OP_CLOSE,bytes,0,bytes.length);
|
||||
_outbound.flush();
|
||||
if (close)
|
||||
_endp.shutdownOutput();
|
||||
}
|
||||
_outbound.flush();
|
||||
else if (close)
|
||||
_endp.close();
|
||||
|
||||
}
|
||||
catch(IOException e)
|
||||
|
@ -712,7 +714,7 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||
String message=null;
|
||||
if (buffer.length()>=2)
|
||||
{
|
||||
code=buffer.array()[buffer.getIndex()]*0x100+buffer.array()[buffer.getIndex()+1];
|
||||
code=(0xff&buffer.array()[buffer.getIndex()])*0x100+(0xff&buffer.array()[buffer.getIndex()+1]);
|
||||
if (buffer.length()>2)
|
||||
message=new String(buffer.array(),buffer.getIndex()+2,buffer.length()-2,StringUtil.__UTF8);
|
||||
}
|
||||
|
@ -780,6 +782,12 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||
}
|
||||
}
|
||||
}
|
||||
catch(Utf8Appendable.NotUtf8Exception notUtf8)
|
||||
{
|
||||
LOG.warn("{} for {}",notUtf8,_endp);
|
||||
LOG.debug(notUtf8);
|
||||
_connection.close(WebSocketConnectionD13.CLOSE_NOT_UTF8,"Invalid UTF-8");
|
||||
}
|
||||
catch(ThreadDeath th)
|
||||
{
|
||||
throw th;
|
||||
|
@ -837,10 +845,6 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||
/* ------------------------------------------------------------ */
|
||||
public void handshake(HttpServletRequest request, HttpServletResponse response, String subprotocol) throws IOException
|
||||
{
|
||||
String uri=request.getRequestURI();
|
||||
String query=request.getQueryString();
|
||||
if (query!=null && query.length()>0)
|
||||
uri+="?"+query;
|
||||
String key = request.getHeader("Sec-WebSocket-Key");
|
||||
|
||||
response.setHeader("Upgrade","WebSocket");
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.util.Enumeration;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
@ -43,16 +42,19 @@ public class WebSocketFactory
|
|||
{
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param request
|
||||
* @param protocol
|
||||
* @returns
|
||||
* <p>Factory method that applications needs to implement to return a
|
||||
* {@link WebSocket} object.</p>
|
||||
* @param request the incoming HTTP upgrade request
|
||||
* @param protocol the websocket sub protocol
|
||||
* @return a new {@link WebSocket} object that will handle websocket events.
|
||||
*/
|
||||
WebSocket doWebSocketConnect(HttpServletRequest request, String protocol);
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Check the origin of an incoming WebSocket handshake request
|
||||
* @param request
|
||||
* @param origin
|
||||
/**
|
||||
* <p>Checks the origin of an incoming WebSocket handshake request.</p>
|
||||
* @param request the incoming HTTP upgrade request
|
||||
* @param origin the origin URI
|
||||
* @return boolean to indicate that the origin is acceptable.
|
||||
*/
|
||||
boolean checkOrigin(HttpServletRequest request, String origin);
|
||||
|
@ -161,7 +163,7 @@ public class WebSocketFactory
|
|||
/**
|
||||
* Set the initial maximum binary message size for a connection. This can be changed by
|
||||
* the application calling {@link WebSocket.Connection#setMaxBinaryMessageSize(int)}.
|
||||
* @param maxTextMessageSize The default maximum binary message size (in bytes) for a connection
|
||||
* @param maxBinaryMessageSize The default maximum binary message size (in bytes) for a connection
|
||||
*/
|
||||
public void setMaxBinaryMessageSize(int maxBinaryMessageSize)
|
||||
{
|
||||
|
|
|
@ -149,8 +149,6 @@ public class WebSocketGeneratorD00 implements WebSocketGenerator
|
|||
{
|
||||
while (_buffer.space()==0)
|
||||
{
|
||||
// TODO: in case the I/O system signals write ready, but when we attempt to write we cannot
|
||||
// TODO: we should decrease the blockFor timeout instead of waiting again the whole timeout
|
||||
boolean ready = _endp.blockWritable(blockFor);
|
||||
if (!ready)
|
||||
throw new IOException("Write timeout");
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
package org.eclipse.jetty.websocket;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
import org.eclipse.jetty.io.Buffer;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
|
@ -100,10 +98,10 @@ public class WebSocketGeneratorD06 implements WebSocketGenerator
|
|||
bufferPut(new byte[]{
|
||||
opcode,
|
||||
(byte)0x7f,
|
||||
(byte)((payload>>56)&0x7f),
|
||||
(byte)((payload>>48)&0xff),
|
||||
(byte)((payload>>40)&0xff),
|
||||
(byte)((payload>>32)&0xff),
|
||||
(byte)0,
|
||||
(byte)0,
|
||||
(byte)0,
|
||||
(byte)0,
|
||||
(byte)((payload>>24)&0xff),
|
||||
(byte)((payload>>16)&0xff),
|
||||
(byte)((payload>>8)&0xff),
|
||||
|
@ -212,8 +210,6 @@ public class WebSocketGeneratorD06 implements WebSocketGenerator
|
|||
{
|
||||
while (_buffer.space()==0)
|
||||
{
|
||||
// TODO: in case the I/O system signals write ready, but when we attempt to write we cannot
|
||||
// TODO: we should decrease the blockFor timeout instead of waiting again the whole timeout
|
||||
boolean ready = _endp.blockWritable(blockFor);
|
||||
if (!ready)
|
||||
throw new IOException("Write timeout");
|
||||
|
|
|
@ -66,7 +66,6 @@ public class WebSocketGeneratorD12 implements WebSocketGenerator
|
|||
_buffer=mask?_buffers.getBuffer():_buffers.getDirectBuffer();
|
||||
|
||||
boolean last=WebSocketConnectionD12.isLastFrame(flags);
|
||||
byte orig=opcode;
|
||||
|
||||
int space=mask?14:10;
|
||||
|
||||
|
@ -100,10 +99,10 @@ public class WebSocketGeneratorD12 implements WebSocketGenerator
|
|||
_buffer.put(new byte[]{
|
||||
opcode,
|
||||
mask?(byte)0xff:(byte)0x7f,
|
||||
(byte)((payload>>56)&0x7f),
|
||||
(byte)((payload>>48)&0xff),
|
||||
(byte)((payload>>40)&0xff),
|
||||
(byte)((payload>>32)&0xff),
|
||||
(byte)0,
|
||||
(byte)0,
|
||||
(byte)0,
|
||||
(byte)0,
|
||||
(byte)((payload>>24)&0xff),
|
||||
(byte)((payload>>16)&0xff),
|
||||
(byte)((payload>>8)&0xff),
|
||||
|
|
|
@ -66,7 +66,6 @@ public class WebSocketGeneratorD13 implements WebSocketGenerator
|
|||
_buffer=mask?_buffers.getBuffer():_buffers.getDirectBuffer();
|
||||
|
||||
boolean last=WebSocketConnectionD13.isLastFrame(flags);
|
||||
byte orig=opcode;
|
||||
|
||||
int space=mask?14:10;
|
||||
|
||||
|
@ -100,10 +99,10 @@ public class WebSocketGeneratorD13 implements WebSocketGenerator
|
|||
_buffer.put(new byte[]{
|
||||
opcode,
|
||||
mask?(byte)0xff:(byte)0x7f,
|
||||
(byte)((payload>>56)&0x7f),
|
||||
(byte)((payload>>48)&0xff),
|
||||
(byte)((payload>>40)&0xff),
|
||||
(byte)((payload>>32)&0xff),
|
||||
(byte)0,
|
||||
(byte)0,
|
||||
(byte)0,
|
||||
(byte)0,
|
||||
(byte)((payload>>24)&0xff),
|
||||
(byte)((payload>>16)&0xff),
|
||||
(byte)((payload>>8)&0xff),
|
||||
|
|
|
@ -51,8 +51,8 @@ public class WebSocketParserD00 implements WebSocketParser
|
|||
* @param buffers The buffers to use for parsing. Only the {@link Buffers#getBuffer()} is used.
|
||||
* This should be a direct buffer if binary data is mostly used or an indirect buffer if utf-8 data
|
||||
* is mostly used.
|
||||
* @param endp
|
||||
* @param handler
|
||||
* @param endp the endpoint
|
||||
* @param handler the handler to notify when a parse event occurs
|
||||
*/
|
||||
public WebSocketParserD00(WebSocketBuffers buffers, EndPoint endp, FrameHandler handler)
|
||||
{
|
||||
|
@ -89,7 +89,6 @@ public class WebSocketParserD00 implements WebSocketParser
|
|||
int total_filled=0;
|
||||
|
||||
// Loop until an datagram call back or can't fill anymore
|
||||
boolean progress=true;
|
||||
while(true)
|
||||
{
|
||||
int length=_buffer.length();
|
||||
|
|
|
@ -47,7 +47,7 @@ public class WebSocketParserD06 implements WebSocketParser
|
|||
{
|
||||
return _needs;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private final WebSocketBuffers _buffers;
|
||||
|
@ -68,8 +68,9 @@ public class WebSocketParserD06 implements WebSocketParser
|
|||
* @param buffers The buffers to use for parsing. Only the {@link Buffers#getBuffer()} is used.
|
||||
* This should be a direct buffer if binary data is mostly used or an indirect buffer if utf-8 data
|
||||
* is mostly used.
|
||||
* @param endp
|
||||
* @param handler
|
||||
* @param endp the endpoint
|
||||
* @param handler the handler to notify when a parse event occurs
|
||||
* @param masked whether masking should be handled
|
||||
*/
|
||||
public WebSocketParserD06(WebSocketBuffers buffers, EndPoint endp, FrameHandler handler, boolean masked)
|
||||
{
|
||||
|
|
|
@ -47,7 +47,7 @@ public class WebSocketParserD12 implements WebSocketParser
|
|||
{
|
||||
return _needs;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private final WebSocketBuffers _buffers;
|
||||
private final EndPoint _endp;
|
||||
|
@ -70,8 +70,9 @@ public class WebSocketParserD12 implements WebSocketParser
|
|||
* @param buffers The buffers to use for parsing. Only the {@link Buffers#getBuffer()} is used.
|
||||
* This should be a direct buffer if binary data is mostly used or an indirect buffer if utf-8 data
|
||||
* is mostly used.
|
||||
* @param endp
|
||||
* @param handler
|
||||
* @param endp the endpoint
|
||||
* @param handler the handler to notify when a parse event occurs
|
||||
* @param shouldBeMasked whether masking should be handled
|
||||
*/
|
||||
public WebSocketParserD12(WebSocketBuffers buffers, EndPoint endp, FrameHandler handler, boolean shouldBeMasked)
|
||||
{
|
||||
|
|
|
@ -47,7 +47,7 @@ public class WebSocketParserD13 implements WebSocketParser
|
|||
{
|
||||
return _needs;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private final WebSocketBuffers _buffers;
|
||||
private final EndPoint _endp;
|
||||
|
@ -70,8 +70,9 @@ public class WebSocketParserD13 implements WebSocketParser
|
|||
* @param buffers The buffers to use for parsing. Only the {@link Buffers#getBuffer()} is used.
|
||||
* This should be a direct buffer if binary data is mostly used or an indirect buffer if utf-8 data
|
||||
* is mostly used.
|
||||
* @param endp
|
||||
* @param handler
|
||||
* @param endp the endpoint
|
||||
* @param handler the handler to notify when a parse event occurs
|
||||
* @param shouldBeMasked whether masking should be handled
|
||||
*/
|
||||
public WebSocketParserD13(WebSocketBuffers buffers, EndPoint endp, FrameHandler handler, boolean shouldBeMasked)
|
||||
{
|
||||
|
|
|
@ -80,7 +80,7 @@ public class WebSocketClientTest
|
|||
{
|
||||
}
|
||||
};
|
||||
Future<WebSocket.Connection> future = client.open(new URI("ws://127.0.0.1:" + _serverPort + "/"), websocket);
|
||||
client.open(new URI("ws://127.0.0.1:" + _serverPort + "/"), websocket);
|
||||
|
||||
Socket socket = _server.accept();
|
||||
accept(socket);
|
||||
|
|
|
@ -909,6 +909,98 @@ public class WebSocketMessageD13Test
|
|||
lookFor("Message size > 15",input);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseCode() throws Exception
|
||||
{
|
||||
Socket socket = new Socket("localhost", __connector.getLocalPort());
|
||||
OutputStream output = socket.getOutputStream();
|
||||
output.write(
|
||||
("GET /chat HTTP/1.1\r\n"+
|
||||
"Host: server.example.com\r\n"+
|
||||
"Upgrade: websocket\r\n"+
|
||||
"Connection: Upgrade\r\n"+
|
||||
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"+
|
||||
"Sec-WebSocket-Origin: http://example.com\r\n"+
|
||||
"Sec-WebSocket-Protocol: chat\r\n" +
|
||||
"Sec-WebSocket-Version: "+WebSocketConnectionD13.VERSION+"\r\n"+
|
||||
"\r\n").getBytes("ISO-8859-1"));
|
||||
output.flush();
|
||||
|
||||
socket.setSoTimeout(100000);
|
||||
InputStream input = socket.getInputStream();
|
||||
|
||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
||||
skipTo("Sec-WebSocket-Accept: ",input);
|
||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
||||
skipTo("\r\n\r\n",input);
|
||||
|
||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
||||
assertNotNull(__serverWebSocket.connection);
|
||||
|
||||
__serverWebSocket.getConnection().setMaxBinaryMessageSize(15);
|
||||
|
||||
output.write(0x88);
|
||||
output.write(0x82);
|
||||
output.write(0x00);
|
||||
output.write(0x00);
|
||||
output.write(0x00);
|
||||
output.write(0x00);
|
||||
output.write(0x81);
|
||||
output.write(0xFF);
|
||||
output.flush();
|
||||
|
||||
assertEquals(0x80|WebSocketConnectionD13.OP_CLOSE,input.read());
|
||||
assertEquals(2,input.read());
|
||||
int code=(0xff&input.read())*0x100+(0xff&input.read());
|
||||
assertEquals(0x81FF,code);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotUTF8() throws Exception
|
||||
{
|
||||
Socket socket = new Socket("localhost", __connector.getLocalPort());
|
||||
OutputStream output = socket.getOutputStream();
|
||||
output.write(
|
||||
("GET /chat HTTP/1.1\r\n"+
|
||||
"Host: server.example.com\r\n"+
|
||||
"Upgrade: websocket\r\n"+
|
||||
"Connection: Upgrade\r\n"+
|
||||
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"+
|
||||
"Sec-WebSocket-Origin: http://example.com\r\n"+
|
||||
"Sec-WebSocket-Protocol: chat\r\n" +
|
||||
"Sec-WebSocket-Version: "+WebSocketConnectionD13.VERSION+"\r\n"+
|
||||
"\r\n").getBytes("ISO-8859-1"));
|
||||
output.flush();
|
||||
|
||||
socket.setSoTimeout(100000);
|
||||
InputStream input = socket.getInputStream();
|
||||
|
||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
||||
skipTo("Sec-WebSocket-Accept: ",input);
|
||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
||||
skipTo("\r\n\r\n",input);
|
||||
|
||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
||||
assertNotNull(__serverWebSocket.connection);
|
||||
|
||||
__serverWebSocket.getConnection().setMaxBinaryMessageSize(15);
|
||||
|
||||
output.write(0x81);
|
||||
output.write(0x82);
|
||||
output.write(0x00);
|
||||
output.write(0x00);
|
||||
output.write(0x00);
|
||||
output.write(0x00);
|
||||
output.write(0xc3);
|
||||
output.write(0x28);
|
||||
output.flush();
|
||||
|
||||
assertEquals(0x80|WebSocketConnectionD13.OP_CLOSE,input.read());
|
||||
assertEquals(15,input.read());
|
||||
int code=(0xff&input.read())*0x100+(0xff&input.read());
|
||||
assertEquals(WebSocketConnectionD13.CLOSE_NOT_UTF8,code);
|
||||
lookFor("Invalid UTF-8",input);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxBinarySize2() throws Exception
|
||||
|
|
|
@ -130,13 +130,6 @@ public class WebSocketParserD00Test
|
|||
}
|
||||
|
||||
|
||||
// TODO test:
|
||||
// blocking,
|
||||
// async
|
||||
// full
|
||||
// EOF
|
||||
// errors
|
||||
|
||||
private class Handler implements WebSocketParser.FrameHandler
|
||||
{
|
||||
public List<String> _data = new ArrayList<String>();
|
||||
|
|
|
@ -242,6 +242,7 @@ public abstract class ContinuationBase extends TestCase
|
|||
try
|
||||
{
|
||||
Socket socket = new Socket("localhost",port);
|
||||
socket.setSoTimeout(10000);
|
||||
socket.getOutputStream().write(request.getBytes("UTF-8"));
|
||||
|
||||
response = toString(socket.getInputStream());
|
||||
|
|
|
@ -173,7 +173,7 @@
|
|||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-websocket</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
<!--scope>provided</scope-->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
|
|
|
@ -36,7 +36,7 @@ public class HashTestServer extends AbstractTestServer
|
|||
}
|
||||
|
||||
|
||||
public SessionIdManager newSessionIdManager()
|
||||
public SessionIdManager newSessionIdManager(String config)
|
||||
{
|
||||
return new HashSessionIdManager();
|
||||
}
|
||||
|
|
|
@ -22,22 +22,29 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
|||
public class JdbcTestServer extends AbstractTestServer
|
||||
{
|
||||
public static final String DRIVER_CLASS = "org.apache.derby.jdbc.EmbeddedDriver";
|
||||
public static final String CONNECTION_URL = "jdbc:derby:sessions;create=true";
|
||||
public static final String DEFAULT_CONNECTION_URL = "jdbc:derby:sessions;create=true";
|
||||
public static final int SAVE_INTERVAL = 1;
|
||||
|
||||
|
||||
static
|
||||
{
|
||||
System.setProperty("derby.system.home", MavenTestingUtils.getTargetFile("test-derby").getAbsolutePath());
|
||||
}
|
||||
|
||||
|
||||
public JdbcTestServer(int port)
|
||||
{
|
||||
super(port);
|
||||
}
|
||||
|
||||
public JdbcTestServer(int port, int maxInactivePeriod, int scavengePeriod, String connectionUrl)
|
||||
{
|
||||
super(port, maxInactivePeriod, scavengePeriod, connectionUrl);
|
||||
}
|
||||
|
||||
public JdbcTestServer(int port, int maxInactivePeriod, int scavengePeriod)
|
||||
{
|
||||
super(port, maxInactivePeriod, scavengePeriod);
|
||||
super(port, maxInactivePeriod, scavengePeriod, DEFAULT_CONNECTION_URL);
|
||||
}
|
||||
|
||||
public JdbcTestServer (int port, boolean optimize)
|
||||
|
@ -60,14 +67,14 @@ public class JdbcTestServer extends AbstractTestServer
|
|||
* @see org.eclipse.jetty.server.session.AbstractTestServer#newSessionIdManager()
|
||||
*/
|
||||
@Override
|
||||
public SessionIdManager newSessionIdManager()
|
||||
public SessionIdManager newSessionIdManager(String config)
|
||||
{
|
||||
synchronized(JdbcTestServer.class)
|
||||
{
|
||||
JDBCSessionIdManager idManager = new JDBCSessionIdManager(_server);
|
||||
idManager.setScavengeInterval(_scavengePeriod);
|
||||
idManager.setWorkerName("w"+(__workers++));
|
||||
idManager.setDriverInfo(DRIVER_CLASS, CONNECTION_URL);
|
||||
idManager.setDriverInfo(DRIVER_CLASS, (config==null?DEFAULT_CONNECTION_URL:config));
|
||||
return idManager;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,16 @@ package org.eclipse.jetty.server.session;
|
|||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.EventListener;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import javax.servlet.http.HttpSessionActivationListener;
|
||||
import javax.servlet.http.HttpSessionEvent;
|
||||
import javax.servlet.http.HttpSessionListener;
|
||||
|
||||
import org.eclipse.jetty.client.ContentExchange;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
|
@ -30,6 +34,8 @@ public abstract class AbstractRemoveSessionTest
|
|||
AbstractTestServer server = createServer(0, 1, scavengePeriod);
|
||||
ServletContextHandler context = server.addContext(contextPath);
|
||||
context.addServlet(TestServlet.class, servletMapping);
|
||||
TestEventListener testListener = new TestEventListener();
|
||||
context.getSessionHandler().addEventListener(testListener);
|
||||
server.start();
|
||||
int port = server.getPort();
|
||||
try
|
||||
|
@ -49,6 +55,8 @@ public abstract class AbstractRemoveSessionTest
|
|||
assertTrue(sessionCookie != null);
|
||||
// Mangle the cookie, replacing Path with $Path, etc.
|
||||
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
|
||||
//ensure sessionCreated listener is called
|
||||
assertTrue (testListener.isCreated());
|
||||
|
||||
//now delete the session
|
||||
exchange = new ContentExchange(true);
|
||||
|
@ -58,6 +66,8 @@ public abstract class AbstractRemoveSessionTest
|
|||
client.send(exchange);
|
||||
exchange.waitForDone();
|
||||
assertEquals(HttpServletResponse.SC_OK,exchange.getResponseStatus());
|
||||
//ensure sessionDestroyed listener is called
|
||||
assertTrue(testListener.isDestroyed());
|
||||
|
||||
|
||||
// The session is not there anymore, but we present an old cookie
|
||||
|
@ -106,4 +116,32 @@ public abstract class AbstractRemoveSessionTest
|
|||
}
|
||||
}
|
||||
|
||||
public static class TestEventListener implements HttpSessionListener
|
||||
{
|
||||
boolean wasCreated;
|
||||
boolean wasDestroyed;
|
||||
|
||||
public void sessionCreated(HttpSessionEvent se)
|
||||
{
|
||||
wasCreated = true;
|
||||
}
|
||||
|
||||
public void sessionDestroyed(HttpSessionEvent se)
|
||||
{
|
||||
wasDestroyed = true;
|
||||
}
|
||||
|
||||
public boolean isDestroyed()
|
||||
{
|
||||
return wasDestroyed;
|
||||
}
|
||||
|
||||
|
||||
public boolean isCreated()
|
||||
{
|
||||
return wasCreated;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,22 +34,31 @@ public abstract class AbstractTestServer
|
|||
protected final ContextHandlerCollection _contexts;
|
||||
protected SessionIdManager _sessionIdManager;
|
||||
|
||||
|
||||
|
||||
public AbstractTestServer(int port)
|
||||
{
|
||||
this(port, 30, 10);
|
||||
}
|
||||
|
||||
public AbstractTestServer(int port, int maxInactivePeriod, int scavengePeriod)
|
||||
{
|
||||
this (port, maxInactivePeriod, scavengePeriod, null);
|
||||
}
|
||||
|
||||
public AbstractTestServer(int port, int maxInactivePeriod, int scavengePeriod, String sessionIdMgrConfig)
|
||||
{
|
||||
_server = new Server(port);
|
||||
_maxInactivePeriod = maxInactivePeriod;
|
||||
_scavengePeriod = scavengePeriod;
|
||||
_contexts = new ContextHandlerCollection();
|
||||
_sessionIdManager = newSessionIdManager();
|
||||
_sessionIdManager = newSessionIdManager(sessionIdMgrConfig);
|
||||
_server.setSessionIdManager(_sessionIdManager);
|
||||
}
|
||||
|
||||
|
||||
public abstract SessionIdManager newSessionIdManager();
|
||||
|
||||
public abstract SessionIdManager newSessionIdManager(String config);
|
||||
public abstract SessionManager newSessionManager();
|
||||
public abstract SessionHandler newSessionHandler(SessionManager sessionManager);
|
||||
|
||||
|
|
Loading…
Reference in New Issue