mirror of
https://github.com/jetty/jetty.project.git
synced 2025-02-26 09:34:56 +00:00
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
|
jetty-8.0.0.v20110901 - 01 September 2011
|
||||||
+ 352565 cookie httponly flag ignored
|
+ 352565 cookie httponly flag ignored
|
||||||
+ 353073 better warnings
|
+ 353073 better warnings
|
||||||
+ 353285 ServletSecurity annotation ignored
|
+ 353285 ServletSecurity annotation ignored
|
||||||
+ 356421 Upgraded websocket to draft 13 support
|
+ 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
|
jetty-7.5.0.RC2 - 30 August 2011
|
||||||
+ 293739 Hide stacks in named log testing. Various other minor log cleanups in
|
+ 293739 Hide stacks in named log testing. Various other minor log cleanups in
|
||||||
output.
|
output.
|
||||||
@ -73,6 +79,12 @@ jetty-7.5.0.RC0 - 15 August 2011
|
|||||||
+ 354397 RewriteRegexRule handles special characters in regex group
|
+ 354397 RewriteRegexRule handles special characters in regex group
|
||||||
+ 354466 Typo in example config of jetty-plus.xml
|
+ 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
|
jetty-7.4.4.v20110707 - 07 July 2011
|
||||||
+ 308851 Converted all jetty-client module tests to JUnit 4
|
+ 308851 Converted all jetty-client module tests to JUnit 4
|
||||||
+ 345268 JDBCSessionManager does not work with maxInactiveInterval = -1
|
+ 345268 JDBCSessionManager does not work with maxInactiveInterval = -1
|
||||||
|
@ -336,7 +336,9 @@ public class HttpFields
|
|||||||
{
|
{
|
||||||
if (__cache.size()>__cacheSize)
|
if (__cache.size()>__cacheSize)
|
||||||
__cache.clear();
|
__cache.clear();
|
||||||
__cache.putIfAbsent(value,buffer);
|
Buffer b=__cache.putIfAbsent(value,buffer);
|
||||||
|
if (b!=null)
|
||||||
|
buffer=b;
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
|
@ -35,8 +35,8 @@ import org.eclipse.jetty.util.StringUtil;
|
|||||||
*/
|
*/
|
||||||
public class GzipResponseWrapper extends HttpServletResponseWrapper
|
public class GzipResponseWrapper extends HttpServletResponseWrapper
|
||||||
{
|
{
|
||||||
public static int DEFAULT_BUFFER_SIZE = 8192;
|
public static final int DEFAULT_BUFFER_SIZE = 8192;
|
||||||
public static int DEFAULT_MIN_GZIP_SIZE = 256;
|
public static final int DEFAULT_MIN_GZIP_SIZE = 256;
|
||||||
|
|
||||||
private HttpServletRequest _request;
|
private HttpServletRequest _request;
|
||||||
private Set<String> _mimeTypes;
|
private Set<String> _mimeTypes;
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
package org.eclipse.jetty.http.security;
|
package org.eclipse.jetty.http.security;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
@ -209,7 +210,7 @@ public class Constraint implements Cloneable, Serializable
|
|||||||
{
|
{
|
||||||
return "SC{" + _name
|
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}")));
|
+ (_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:
|
case 1:
|
||||||
buf.append('0');
|
buf.append('0');
|
||||||
|
buf.append('0');
|
||||||
|
buf.append('0');
|
||||||
|
buf.append(x);
|
||||||
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
buf.append('0');
|
buf.append('0');
|
||||||
|
buf.append('0');
|
||||||
|
buf.append(x);
|
||||||
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
buf.append('0');
|
buf.append('0');
|
||||||
|
buf.append(x);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
buf.append(x);
|
buf.append(x);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
|
@ -387,7 +387,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
|||||||
|
|
||||||
private final ConcurrentLinkedQueue<Object> _changes = new ConcurrentLinkedQueue<Object>();
|
private final ConcurrentLinkedQueue<Object> _changes = new ConcurrentLinkedQueue<Object>();
|
||||||
|
|
||||||
private Selector _selector;
|
private volatile Selector _selector;
|
||||||
|
|
||||||
private volatile Thread _selecting;
|
private volatile Thread _selecting;
|
||||||
private int _jvmBug;
|
private int _jvmBug;
|
||||||
@ -975,7 +975,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
|||||||
// close endpoints and selector
|
// close endpoints and selector
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
for (SelectionKey key:_selector.keys())
|
Selector selector=_selector;
|
||||||
|
for (SelectionKey key:selector.keys())
|
||||||
{
|
{
|
||||||
if (key==null)
|
if (key==null)
|
||||||
continue;
|
continue;
|
||||||
@ -998,8 +999,9 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
|||||||
_timeout.cancelAll();
|
_timeout.cancelAll();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_selector != null)
|
selector=_selector;
|
||||||
_selector.close();
|
if (selector != null)
|
||||||
|
selector.close();
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
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);
|
LOG.debug(x);
|
||||||
super.close();
|
super.close();
|
||||||
@ -444,8 +449,11 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
|||||||
case BUFFER_OVERFLOW:
|
case BUFFER_OVERFLOW:
|
||||||
case BUFFER_UNDERFLOW:
|
case BUFFER_UNDERFLOW:
|
||||||
LOG.warn("wrap {}",_result);
|
LOG.warn("wrap {}",_result);
|
||||||
|
_closing=true;
|
||||||
|
break;
|
||||||
case CLOSED:
|
case CLOSED:
|
||||||
_closing=true;
|
_closing=true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_outNIOBuffer.setPutIndex(put+_result.bytesProduced());
|
_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
|
public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
|
||||||
{
|
{
|
||||||
int consumed=0;
|
int consumed=0;
|
||||||
int available=header.length();
|
int available=header==null?0:header.length();
|
||||||
if (buffer!=null)
|
if (buffer!=null)
|
||||||
available+=buffer.length();
|
available+=buffer.length();
|
||||||
|
|
||||||
@ -599,8 +607,11 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
|||||||
case BUFFER_OVERFLOW:
|
case BUFFER_OVERFLOW:
|
||||||
case BUFFER_UNDERFLOW:
|
case BUFFER_UNDERFLOW:
|
||||||
LOG.warn("unwrap {}",_result);
|
LOG.warn("unwrap {}",_result);
|
||||||
|
_closing=true;
|
||||||
|
break;
|
||||||
case CLOSED:
|
case CLOSED:
|
||||||
_closing=true;
|
_closing=true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
_outNIOBuffer.setPutIndex(put+_result.bytesProduced());
|
_outNIOBuffer.setPutIndex(put+_result.bytesProduced());
|
||||||
}
|
}
|
||||||
@ -895,6 +906,8 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
|||||||
case BUFFER_OVERFLOW:
|
case BUFFER_OVERFLOW:
|
||||||
case BUFFER_UNDERFLOW:
|
case BUFFER_UNDERFLOW:
|
||||||
LOG.warn("unwrap {}",_result);
|
LOG.warn("unwrap {}",_result);
|
||||||
|
_closing=true;
|
||||||
|
return _result.bytesConsumed()>0?_result.bytesConsumed():-1;
|
||||||
|
|
||||||
case OK:
|
case OK:
|
||||||
return _result.bytesConsumed();
|
return _result.bytesConsumed();
|
||||||
@ -965,6 +978,8 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
|||||||
case BUFFER_OVERFLOW:
|
case BUFFER_OVERFLOW:
|
||||||
case BUFFER_UNDERFLOW:
|
case BUFFER_UNDERFLOW:
|
||||||
LOG.warn("unwrap {}",_result);
|
LOG.warn("unwrap {}",_result);
|
||||||
|
_closing=true;
|
||||||
|
return _result.bytesConsumed()>0?_result.bytesConsumed():-1;
|
||||||
|
|
||||||
case OK:
|
case OK:
|
||||||
return _result.bytesConsumed();
|
return _result.bytesConsumed();
|
||||||
|
@ -42,33 +42,4 @@ public class IOTest
|
|||||||
out.toString(),
|
out.toString(),
|
||||||
"The quick brown fox jumped over the lazy dog");
|
"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>
|
<version>${project.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-websocket</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-server</artifactId>
|
<artifactId>jetty-server</artifactId>
|
||||||
|
@ -52,7 +52,7 @@ public class MongoTestServer extends AbstractTestServer
|
|||||||
_saveAllAttributes = saveAllAttributes;
|
_saveAllAttributes = saveAllAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SessionIdManager newSessionIdManager()
|
public SessionIdManager newSessionIdManager(String config)
|
||||||
{
|
{
|
||||||
if ( _idManager != null )
|
if ( _idManager != null )
|
||||||
{
|
{
|
||||||
|
@ -73,17 +73,14 @@ public class PolicyMonitorTest
|
|||||||
monitor.setScanInterval(1);
|
monitor.setScanInterval(1);
|
||||||
|
|
||||||
monitor.start();
|
monitor.start();
|
||||||
|
monitor.waitForScan();
|
||||||
while (! monitor.isInitialized() )
|
monitor.waitForScan();
|
||||||
{
|
|
||||||
Thread.sleep(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
File permFile =new File(MavenTestingUtils.getTargetDir(),
|
File permFile =new File(MavenTestingUtils.getTargetDir(),
|
||||||
"test-classes/monitor-test-2/global-all-permission.policy");
|
"test-classes/monitor-test-2/global-all-permission.policy");
|
||||||
|
|
||||||
// Wait so that time is definitely different
|
// Wait so that time is definitely different
|
||||||
Thread.sleep(10);
|
monitor.waitForScan();
|
||||||
permFile.setLastModified(System.currentTimeMillis());
|
permFile.setLastModified(System.currentTimeMillis());
|
||||||
|
|
||||||
monitor.waitForScan();
|
monitor.waitForScan();
|
||||||
|
@ -115,6 +115,7 @@ public class DigestAuthenticator extends LoginAuthenticator
|
|||||||
break;
|
break;
|
||||||
case ',':
|
case ',':
|
||||||
name = null;
|
name = null;
|
||||||
|
break;
|
||||||
case ' ':
|
case ' ':
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -704,7 +704,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
|
|||||||
{
|
{
|
||||||
HttpSessionEvent event=new HttpSessionEvent(session);
|
HttpSessionEvent event=new HttpSessionEvent(session);
|
||||||
for (HttpSessionListener listener : _sessionListeners)
|
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"+
|
response=connector.getResponses("GET /foo/bar%c0%00 HTTP/1.1\n"+
|
||||||
"Host: localhost\n"+
|
"Host: localhost\n"+
|
||||||
"\015\012");
|
"\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"+
|
response=connector.getResponses("GET /bad/utf8%c1 HTTP/1.1\n"+
|
||||||
"Host: localhost\n"+
|
"Host: localhost\n"+
|
||||||
|
@ -148,7 +148,9 @@ public class ServletContextHandler extends ContextHandler
|
|||||||
protected void doStop() throws Exception
|
protected void doStop() throws Exception
|
||||||
{
|
{
|
||||||
super.doStop();
|
super.doStop();
|
||||||
|
if (_decorators != null)
|
||||||
_decorators.clear();
|
_decorators.clear();
|
||||||
|
if (_wrapper != null)
|
||||||
_wrapper.setHandler(null);
|
_wrapper.setHandler(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.eclipse.jetty.util;
|
package org.eclipse.jetty.util;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.IllegalFormatCodePointException;
|
||||||
|
|
||||||
public abstract class Utf8Appendable
|
public abstract class Utf8Appendable
|
||||||
{
|
{
|
||||||
@ -69,6 +70,7 @@ public abstract class Utf8Appendable
|
|||||||
_appendable.append('?');
|
_appendable.append('?');
|
||||||
_more=0;
|
_more=0;
|
||||||
_bits=0;
|
_bits=0;
|
||||||
|
throw new NotUtf8Exception();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
_appendable.append((char)(0x7f&b));
|
_appendable.append((char)(0x7f&b));
|
||||||
@ -81,6 +83,7 @@ public abstract class Utf8Appendable
|
|||||||
_appendable.append('?');
|
_appendable.append('?');
|
||||||
_more=0;
|
_more=0;
|
||||||
_bits=0;
|
_bits=0;
|
||||||
|
throw new NotUtf8Exception();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -116,7 +119,7 @@ public abstract class Utf8Appendable
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("!utf8");
|
throw new NotUtf8Exception();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,7 +130,7 @@ public abstract class Utf8Appendable
|
|||||||
_appendable.append('?');
|
_appendable.append('?');
|
||||||
_more=0;
|
_more=0;
|
||||||
_bits=0;
|
_bits=0;
|
||||||
throw new IllegalArgumentException("!utf8");
|
throw new NotUtf8Exception();
|
||||||
}
|
}
|
||||||
else
|
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()
|
public StringBuffer getStringBuffer()
|
||||||
{
|
{
|
||||||
if (_more!=0)
|
if (_more!=0)
|
||||||
throw new IllegalStateException("!utf8");
|
throw new NotUtf8Exception();
|
||||||
return _buffer;
|
return _buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ public class Utf8StringBuffer extends Utf8Appendable
|
|||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
if (_more!=0)
|
if (_more!=0)
|
||||||
throw new IllegalStateException("!utf8");
|
throw new NotUtf8Exception();
|
||||||
return _buffer.toString();
|
return _buffer.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ public class Utf8StringBuilder extends Utf8Appendable
|
|||||||
public StringBuilder getStringBuilder()
|
public StringBuilder getStringBuilder()
|
||||||
{
|
{
|
||||||
if (_more!=0)
|
if (_more!=0)
|
||||||
throw new IllegalStateException("!utf8");
|
throw new NotUtf8Exception();
|
||||||
return _buffer;
|
return _buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ public class Utf8StringBuilder extends Utf8Appendable
|
|||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
if (_more!=0)
|
if (_more!=0)
|
||||||
throw new IllegalStateException("!utf8");
|
throw new NotUtf8Exception();
|
||||||
return _buffer.toString();
|
return _buffer.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,8 +166,7 @@ public abstract class Resource implements ResourceFactory
|
|||||||
|
|
||||||
URLConnection connection=url.openConnection();
|
URLConnection connection=url.openConnection();
|
||||||
connection.setUseCaches(useCaches);
|
connection.setUseCaches(useCaches);
|
||||||
FileResource fileResource= new FileResource(url,connection,file);
|
return new FileResource(url,connection,file);
|
||||||
return fileResource;
|
|
||||||
}
|
}
|
||||||
catch(Exception e2)
|
catch(Exception e2)
|
||||||
{
|
{
|
||||||
@ -199,6 +198,18 @@ public abstract class Resource implements ResourceFactory
|
|||||||
return newResource(url);
|
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.
|
/** Construct a system resource from a string.
|
||||||
* The resource is tried as classloader resource before being
|
* The resource is tried as classloader resource before being
|
||||||
|
@ -50,7 +50,7 @@ public class Utf8StringBufferTest
|
|||||||
}
|
}
|
||||||
catch(IllegalStateException e)
|
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;
|
bytes[4]=(byte)0x00;
|
||||||
|
|
||||||
Utf8StringBuffer buffer = new Utf8StringBuffer();
|
Utf8StringBuffer buffer = new Utf8StringBuffer();
|
||||||
|
try
|
||||||
|
{
|
||||||
for (int i=0;i<bytes.length;i++)
|
for (int i=0;i<bytes.length;i++)
|
||||||
buffer.append(bytes[i]);
|
buffer.append(bytes[i]);
|
||||||
|
assertTrue(false);
|
||||||
|
}
|
||||||
|
catch(IllegalStateException e)
|
||||||
|
{
|
||||||
|
assertTrue(e.toString().indexOf("!UTF-8")>=0);
|
||||||
|
}
|
||||||
assertEquals("abc?",buffer.toString());
|
assertEquals("abc?",buffer.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ public class Utf8StringBuilderTest
|
|||||||
}
|
}
|
||||||
catch(IllegalStateException e)
|
catch(IllegalStateException e)
|
||||||
{
|
{
|
||||||
assertTrue(e.toString().indexOf("!utf8")>=0);
|
assertTrue(e.toString().indexOf("!UTF-8")>=0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,8 +64,16 @@ public class Utf8StringBuilderTest
|
|||||||
bytes[4]=(byte)0x00;
|
bytes[4]=(byte)0x00;
|
||||||
|
|
||||||
Utf8StringBuilder buffer = new Utf8StringBuilder();
|
Utf8StringBuilder buffer = new Utf8StringBuilder();
|
||||||
|
try
|
||||||
|
{
|
||||||
for (int i = 0; i < bytes.length; i++)
|
for (int i = 0; i < bytes.length; i++)
|
||||||
buffer.append(bytes[i]);
|
buffer.append(bytes[i]);
|
||||||
|
assertTrue(false);
|
||||||
|
}
|
||||||
|
catch(IllegalStateException e)
|
||||||
|
{
|
||||||
|
assertTrue(e.toString().indexOf("!UTF-8")>=0);
|
||||||
|
}
|
||||||
assertEquals("abc?", buffer.toString());
|
assertEquals("abc?", buffer.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@ import java.util.EventListener;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.http.HttpSessionActivationListener;
|
import javax.servlet.http.HttpSessionActivationListener;
|
||||||
import javax.servlet.http.HttpSessionAttributeListener;
|
import javax.servlet.http.HttpSessionAttributeListener;
|
||||||
@ -99,7 +98,8 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||||||
"org.eclipse.jetty.continuation.", // webapp cannot change continuation classes
|
"org.eclipse.jetty.continuation.", // webapp cannot change continuation classes
|
||||||
"org.eclipse.jetty.jndi.", // webapp cannot change naming classes
|
"org.eclipse.jetty.jndi.", // webapp cannot change naming classes
|
||||||
"org.eclipse.jetty.plus.jaas.", // webapp cannot change jaas classes
|
"org.eclipse.jetty.plus.jaas.", // webapp cannot change jaas classes
|
||||||
"org.eclipse.jetty.websocket.", // WebSocket is a jetty 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" // webapp cannot change default servlets
|
"org.eclipse.jetty.servlet.DefaultServlet" // webapp cannot change default servlets
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
@ -112,7 +112,8 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||||||
"-org.eclipse.jetty.continuation.", // don't hide continuation classes
|
"-org.eclipse.jetty.continuation.", // don't hide continuation classes
|
||||||
"-org.eclipse.jetty.jndi.", // don't hide naming classes
|
"-org.eclipse.jetty.jndi.", // don't hide naming classes
|
||||||
"-org.eclipse.jetty.plus.jaas.", // don't hide jaas 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.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
|
"org.eclipse.jetty." // hide other jetty classes
|
||||||
|
@ -1,33 +1,54 @@
|
|||||||
|
|
||||||
<?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">
|
<?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>
|
<parent>
|
||||||
<artifactId>jetty-project</artifactId>
|
<artifactId>jetty-project</artifactId>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<version>8.0.1-SNAPSHOT</version>
|
<version>8.0.1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-websocket</artifactId>
|
<artifactId>jetty-websocket</artifactId>
|
||||||
<name>Jetty :: Websocket</name>
|
<name>Jetty :: Websocket</name>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<bundle-symbolic-name>${project.groupId}.websocket</bundle-symbolic-name>
|
<bundle-symbolic-name>${project.groupId}.websocket</bundle-symbolic-name>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-server</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${servlet.spec.groupId}</groupId>
|
<groupId>${servlet.spec.groupId}</groupId>
|
||||||
<artifactId>${servlet.spec.artifactId}</artifactId>
|
<artifactId>${servlet.spec.artifactId}</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-test-helper</artifactId>
|
<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>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
@ -11,6 +11,9 @@ import org.eclipse.jetty.io.ByteArrayBuffer;
|
|||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @TODO Implement proposed deflate frame draft
|
||||||
|
*/
|
||||||
public class DeflateFrameExtension extends AbstractExtension
|
public class DeflateFrameExtension extends AbstractExtension
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(DeflateFrameExtension.class);
|
private static final Logger LOG = Log.getLogger(DeflateFrameExtension.class);
|
||||||
@ -113,10 +116,10 @@ public class DeflateFrameExtension extends AbstractExtension
|
|||||||
if (length>0xffff)
|
if (length>0xffff)
|
||||||
{
|
{
|
||||||
out[out_offset++]=0x7f;
|
out[out_offset++]=0x7f;
|
||||||
out[out_offset++]=(byte)((length>>56)&0x7f);
|
out[out_offset++]=(byte)0;
|
||||||
out[out_offset++]=(byte)((length>>48)&0xff);
|
out[out_offset++]=(byte)0;
|
||||||
out[out_offset++]=(byte)((length>>40)&0xff);
|
out[out_offset++]=(byte)0;
|
||||||
out[out_offset++]=(byte)((length>>32)&0xff);
|
out[out_offset++]=(byte)0;
|
||||||
out[out_offset++]=(byte)((length>>24)&0xff);
|
out[out_offset++]=(byte)((length>>24)&0xff);
|
||||||
out[out_offset++]=(byte)((length>>16)&0xff);
|
out[out_offset++]=(byte)((length>>16)&0xff);
|
||||||
out[out_offset++]=(byte)((length>>8)&0xff);
|
out[out_offset++]=(byte)((length>>8)&0xff);
|
||||||
@ -125,7 +128,7 @@ public class DeflateFrameExtension extends AbstractExtension
|
|||||||
else if (length >=0x7e)
|
else if (length >=0x7e)
|
||||||
{
|
{
|
||||||
out[out_offset++]=0x7e;
|
out[out_offset++]=0x7e;
|
||||||
out[out_offset++]=(byte)(byte)(length>>8);
|
out[out_offset++]=(byte)(length>>8);
|
||||||
out[out_offset++]=(byte)(length&0xff);
|
out[out_offset++]=(byte)(length&0xff);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3,22 +3,23 @@ package org.eclipse.jetty.websocket;
|
|||||||
|
|
||||||
public class FixedMaskGen implements MaskGen
|
public class FixedMaskGen implements MaskGen
|
||||||
{
|
{
|
||||||
final byte[] _mask;
|
private final byte[] _mask;
|
||||||
|
|
||||||
public FixedMaskGen()
|
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)
|
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)
|
public void genMask(byte[] mask)
|
||||||
{
|
{
|
||||||
mask[0]=_mask[0];
|
System.arraycopy(_mask, 0, mask, 0, 4);
|
||||||
mask[1]=_mask[1];
|
|
||||||
mask[2]=_mask[2];
|
|
||||||
mask[3]=_mask[3];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,10 +5,11 @@ import java.util.Random;
|
|||||||
|
|
||||||
public class RandomMaskGen implements MaskGen
|
public class RandomMaskGen implements MaskGen
|
||||||
{
|
{
|
||||||
final Random _random;
|
private final Random _random;
|
||||||
|
|
||||||
public RandomMaskGen()
|
public RandomMaskGen()
|
||||||
{
|
{
|
||||||
_random=new Random();
|
this(new Random());
|
||||||
}
|
}
|
||||||
|
|
||||||
public RandomMaskGen(Random random)
|
public RandomMaskGen(Random random)
|
||||||
@ -18,6 +19,9 @@ public class RandomMaskGen implements MaskGen
|
|||||||
|
|
||||||
public void genMask(byte[] mask)
|
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);
|
_random.nextBytes(mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -31,12 +31,11 @@ public class WebSocketBuffers
|
|||||||
{
|
{
|
||||||
final private int _bufferSize;
|
final private int _bufferSize;
|
||||||
final private Buffers _buffers;
|
final private Buffers _buffers;
|
||||||
final private int _maxBuffers=-1;
|
|
||||||
|
|
||||||
public WebSocketBuffers(final int bufferSize)
|
public WebSocketBuffers(final int bufferSize)
|
||||||
{
|
{
|
||||||
_bufferSize=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()
|
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
|
* Set the initial maximum binary message size for a connection. This can be changed by
|
||||||
* the application calling {@link WebSocket.Connection#setMaxBinaryMessageSize(int)}.
|
* 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)
|
public void setMaxBinaryMessageSize(int maxBinaryMessageSize)
|
||||||
{
|
{
|
||||||
@ -382,19 +382,20 @@ public class WebSocketClient
|
|||||||
connection.getConnection().setMaxTextMessageSize(_maxTextMessageSize);
|
connection.getConnection().setMaxTextMessageSize(_maxTextMessageSize);
|
||||||
connection.getConnection().setMaxBinaryMessageSize(_maxBinaryMessageSize);
|
connection.getConnection().setMaxBinaryMessageSize(_maxBinaryMessageSize);
|
||||||
|
|
||||||
|
WebSocketConnection con;
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
if (_channel!=null)
|
if (_channel!=null)
|
||||||
_connection=connection;
|
_connection=connection;
|
||||||
|
con=_connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_connection!=null)
|
if (con!=null)
|
||||||
{
|
{
|
||||||
if (_websocket instanceof WebSocket.OnFrame)
|
if (_websocket instanceof WebSocket.OnFrame)
|
||||||
((WebSocket.OnFrame)_websocket).onHandshake((WebSocket.FrameConnection)connection.getConnection());
|
((WebSocket.OnFrame)_websocket).onHandshake((WebSocket.FrameConnection)con.getConnection());
|
||||||
|
|
||||||
_websocket.onOpen(connection.getConnection());
|
|
||||||
|
|
||||||
|
_websocket.onOpen(con.getConnection());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
@ -320,34 +320,41 @@ public class WebSocketClientFactory extends AggregateLifeCycle
|
|||||||
|
|
||||||
String origin = future.getOrigin();
|
String origin = future.getOrigin();
|
||||||
|
|
||||||
String request=
|
StringBuilder request = new StringBuilder(512);
|
||||||
"GET "+path+" HTTP/1.1\r\n"+
|
request
|
||||||
"Host: "+future.getURI().getHost()+":"+_future.getURI().getPort()+"\r\n"+
|
.append("GET ").append(path).append(" HTTP/1.1\r\n")
|
||||||
"Upgrade: websocket\r\n"+
|
.append("Host: ").append(future.getURI().getHost()).append(":").append(_future.getURI().getPort()).append("\r\n")
|
||||||
"Connection: Upgrade\r\n"+
|
.append("Upgrade: websocket\r\n")
|
||||||
"Sec-WebSocket-Key: "+_key+"\r\n"+
|
.append("Connection: Upgrade\r\n")
|
||||||
(origin==null?"":"Origin: "+origin+"\r\n")+
|
.append("Sec-WebSocket-Key: ")
|
||||||
"Sec-WebSocket-Version: "+WebSocketConnectionD13.VERSION+"\r\n";
|
.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)
|
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)
|
if (future.getCookies()!=null && future.getCookies().size()>0)
|
||||||
{
|
{
|
||||||
for (String cookie : future.getCookies().keySet())
|
for (String cookie : future.getCookies().keySet())
|
||||||
request+="Cookie: "+QuotedStringTokenizer.quoteIfNeeded(cookie,HttpFields.__COOKIE_DELIM)+
|
request
|
||||||
"="+
|
.append("Cookie: ")
|
||||||
QuotedStringTokenizer.quoteIfNeeded(future.getCookies().get(cookie),HttpFields.__COOKIE_DELIM)+
|
.append(QuotedStringTokenizer.quoteIfNeeded(cookie,HttpFields.__COOKIE_DELIM))
|
||||||
"\r\n";
|
.append("=")
|
||||||
|
.append(QuotedStringTokenizer.quoteIfNeeded(future.getCookies().get(cookie),HttpFields.__COOKIE_DELIM))
|
||||||
|
.append("\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
request+="\r\n";
|
request.append("\r\n");
|
||||||
|
|
||||||
// TODO extensions
|
// TODO extensions
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Buffer handshake = new ByteArrayBuffer(request,false);
|
Buffer handshake = new ByteArrayBuffer(request.toString(),false);
|
||||||
int len=handshake.length();
|
int len=handshake.length();
|
||||||
if (len!=_endp.flush(handshake))
|
if (len!=_endp.flush(handshake))
|
||||||
throw new IOException("incomplete");
|
throw new IOException("incomplete");
|
||||||
|
@ -18,10 +18,10 @@ import java.security.MessageDigest;
|
|||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.http.HttpURI;
|
||||||
import org.eclipse.jetty.io.AbstractConnection;
|
import org.eclipse.jetty.io.AbstractConnection;
|
||||||
import org.eclipse.jetty.io.AsyncEndPoint;
|
import org.eclipse.jetty.io.AsyncEndPoint;
|
||||||
import org.eclipse.jetty.io.Buffer;
|
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.EndPoint;
|
||||||
import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
|
import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
|
||||||
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
|
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
|
||||||
|
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
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.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.WebSocket.OnFrame;
|
import org.eclipse.jetty.websocket.WebSocket.OnFrame;
|
||||||
@ -65,7 +65,7 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
|
|||||||
_protocol=protocol;
|
_protocol=protocol;
|
||||||
|
|
||||||
_generator = new WebSocketGeneratorD00(buffers, _endp);
|
_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)
|
if (_endp instanceof SelectChannelEndPoint)
|
||||||
{
|
{
|
||||||
@ -348,11 +348,9 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
|
|||||||
fodder[5]=(byte)(0xff&(key2>>16));
|
fodder[5]=(byte)(0xff&(key2>>16));
|
||||||
fodder[6]=(byte)(0xff&(key2>>8));
|
fodder[6]=(byte)(0xff&(key2>>8));
|
||||||
fodder[7]=(byte)(0xff&key2);
|
fodder[7]=(byte)(0xff&key2);
|
||||||
for (int i=0;i<8;i++)
|
System.arraycopy(key3, 0, fodder, 8, 8);
|
||||||
fodder[8+i]=key3[i];
|
|
||||||
md.update(fodder);
|
md.update(fodder);
|
||||||
byte[] result=md.digest();
|
return md.digest();
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
catch (NoSuchAlgorithmException e)
|
catch (NoSuchAlgorithmException e)
|
||||||
{
|
{
|
||||||
@ -371,11 +369,15 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
|
|||||||
String query=request.getQueryString();
|
String query=request.getQueryString();
|
||||||
if (query!=null && query.length()>0)
|
if (query!=null && query.length()>0)
|
||||||
uri+="?"+query;
|
uri+="?"+query;
|
||||||
|
uri=new HttpURI(uri).toString();
|
||||||
String host=request.getHeader("Host");
|
String host=request.getHeader("Host");
|
||||||
|
|
||||||
String origin=request.getHeader("Sec-WebSocket-Origin");
|
String origin=request.getHeader("Sec-WebSocket-Origin");
|
||||||
if (origin==null)
|
if (origin==null)
|
||||||
origin=request.getHeader("Origin");
|
origin=request.getHeader("Origin");
|
||||||
|
if (origin!=null)
|
||||||
|
origin= QuotedStringTokenizer.quoteIfNeeded(origin, "\r\n");
|
||||||
|
|
||||||
|
|
||||||
String key1 = request.getHeader("Sec-WebSocket-Key1");
|
String key1 = request.getHeader("Sec-WebSocket-Key1");
|
||||||
|
|
||||||
@ -449,12 +451,11 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
|
|||||||
return _protocol;
|
return _protocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
class FrameHandlerD0 implements WebSocketParser.FrameHandler
|
static class FrameHandlerD00 implements WebSocketParser.FrameHandler
|
||||||
{
|
{
|
||||||
final WebSocket _websocket;
|
final WebSocket _websocket;
|
||||||
final Utf8StringBuilder _utf8 = new Utf8StringBuilder();
|
|
||||||
|
|
||||||
FrameHandlerD0(WebSocket websocket)
|
FrameHandlerD00(WebSocket websocket)
|
||||||
{
|
{
|
||||||
_websocket=websocket;
|
_websocket=websocket;
|
||||||
}
|
}
|
||||||
@ -488,7 +489,6 @@ public class WebSocketConnectionD00 extends AbstractConnection implements WebSoc
|
|||||||
|
|
||||||
public void close(int code,String message)
|
public void close(int code,String message)
|
||||||
{
|
{
|
||||||
close(code,message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ import java.io.UnsupportedEncodingException;
|
|||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
@ -85,8 +84,8 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
|
|||||||
private final OnTextMessage _onTextMessage;
|
private final OnTextMessage _onTextMessage;
|
||||||
private final OnControl _onControl;
|
private final OnControl _onControl;
|
||||||
private final String _protocol;
|
private final String _protocol;
|
||||||
private boolean _closedIn;
|
private volatile boolean _closedIn;
|
||||||
private boolean _closedOut;
|
private volatile boolean _closedOut;
|
||||||
private int _maxTextMessageSize;
|
private int _maxTextMessageSize;
|
||||||
private int _maxBinaryMessageSize=-1;
|
private int _maxBinaryMessageSize=-1;
|
||||||
|
|
||||||
@ -116,7 +115,6 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
|
|||||||
{
|
{
|
||||||
super(endpoint,timestamp);
|
super(endpoint,timestamp);
|
||||||
|
|
||||||
// TODO - can we use the endpoint idle mechanism?
|
|
||||||
if (endpoint instanceof AsyncEndPoint)
|
if (endpoint instanceof AsyncEndPoint)
|
||||||
((AsyncEndPoint)endpoint).cancelIdle();
|
((AsyncEndPoint)endpoint).cancelIdle();
|
||||||
|
|
||||||
@ -131,7 +129,6 @@ public class WebSocketConnectionD06 extends AbstractConnection implements WebSoc
|
|||||||
_parser = new WebSocketParserD06(buffers, endpoint, _frameHandler,true);
|
_parser = new WebSocketParserD06(buffers, endpoint, _frameHandler,true);
|
||||||
_protocol=protocol;
|
_protocol=protocol;
|
||||||
|
|
||||||
// TODO should these be AsyncEndPoint checks/calls?
|
|
||||||
if (_endp instanceof SelectChannelEndPoint)
|
if (_endp instanceof SelectChannelEndPoint)
|
||||||
{
|
{
|
||||||
final SelectChannelEndPoint scep=(SelectChannelEndPoint)_endp;
|
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
|
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");
|
String key = request.getHeader("Sec-WebSocket-Key");
|
||||||
|
|
||||||
response.setHeader("Upgrade","WebSocket");
|
response.setHeader("Upgrade","WebSocket");
|
||||||
|
@ -18,7 +18,6 @@ import java.io.UnsupportedEncodingException;
|
|||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
@ -164,7 +163,6 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc
|
|||||||
|
|
||||||
_protocol=protocol;
|
_protocol=protocol;
|
||||||
|
|
||||||
// TODO should these be AsyncEndPoint checks/calls?
|
|
||||||
if (_endp instanceof SelectChannelEndPoint)
|
if (_endp instanceof SelectChannelEndPoint)
|
||||||
{
|
{
|
||||||
final SelectChannelEndPoint scep=(SelectChannelEndPoint)_endp;
|
final SelectChannelEndPoint scep=(SelectChannelEndPoint)_endp;
|
||||||
@ -762,7 +760,6 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc
|
|||||||
else if (_connection.getMaxBinaryMessageSize()>=0)
|
else if (_connection.getMaxBinaryMessageSize()>=0)
|
||||||
{
|
{
|
||||||
_opcode=opcode;
|
_opcode=opcode;
|
||||||
// TODO use a growing buffer rather than a fixed one.
|
|
||||||
if (_aggregate==null)
|
if (_aggregate==null)
|
||||||
_aggregate=new ByteArrayBuffer(_connection.getMaxBinaryMessageSize());
|
_aggregate=new ByteArrayBuffer(_connection.getMaxBinaryMessageSize());
|
||||||
_aggregate.put(buffer);
|
_aggregate.put(buffer);
|
||||||
@ -833,10 +830,6 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc
|
|||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public void handshake(HttpServletRequest request, HttpServletResponse response, String subprotocol) throws IOException
|
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");
|
String key = request.getHeader("Sec-WebSocket-Key");
|
||||||
|
|
||||||
response.setHeader("Upgrade", "WebSocket");
|
response.setHeader("Upgrade", "WebSocket");
|
||||||
|
@ -18,7 +18,6 @@ import java.io.UnsupportedEncodingException;
|
|||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
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.io.nio.SelectChannelEndPoint;
|
||||||
import org.eclipse.jetty.util.B64Code;
|
import org.eclipse.jetty.util.B64Code;
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
|
import org.eclipse.jetty.util.Utf8Appendable;
|
||||||
import org.eclipse.jetty.util.Utf8StringBuilder;
|
import org.eclipse.jetty.util.Utf8StringBuilder;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
@ -84,7 +84,6 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||||||
private final IdleCheck _idle;
|
private final IdleCheck _idle;
|
||||||
private final List<Extension> _extensions;
|
private final List<Extension> _extensions;
|
||||||
private final WebSocketParserD13 _parser;
|
private final WebSocketParserD13 _parser;
|
||||||
private final WebSocketParser.FrameHandler _inbound;
|
|
||||||
private final WebSocketGeneratorD13 _generator;
|
private final WebSocketGeneratorD13 _generator;
|
||||||
private final WebSocketGenerator _outbound;
|
private final WebSocketGenerator _outbound;
|
||||||
private final WebSocket _webSocket;
|
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();
|
private final WebSocket.FrameConnection _connection = new WSFrameConnection();
|
||||||
|
|
||||||
|
|
||||||
@ -148,6 +145,7 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||||||
_generator = new WebSocketGeneratorD13(buffers, _endp,maskgen);
|
_generator = new WebSocketGeneratorD13(buffers, _endp,maskgen);
|
||||||
|
|
||||||
_extensions=extensions;
|
_extensions=extensions;
|
||||||
|
WebSocketParser.FrameHandler frameHandler = new WSFrameHandler();
|
||||||
if (_extensions!=null)
|
if (_extensions!=null)
|
||||||
{
|
{
|
||||||
int e=0;
|
int e=0;
|
||||||
@ -155,16 +153,16 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||||||
{
|
{
|
||||||
extension.bind(
|
extension.bind(
|
||||||
_connection,
|
_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==0?_generator:extensions.get(e-1));
|
||||||
e++;
|
e++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_outbound=(_extensions==null||_extensions.size()==0)?_generator:extensions.get(extensions.size()-1);
|
_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;
|
_protocol=protocol;
|
||||||
|
|
||||||
@ -302,14 +300,14 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||||||
{
|
{
|
||||||
LOG.debug("ClosedIn {} {}",this,message);
|
LOG.debug("ClosedIn {} {}",this,message);
|
||||||
|
|
||||||
final boolean closedOut;
|
final boolean close;
|
||||||
final boolean closed;
|
final boolean tell_app;
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
closedOut=_closedOut;
|
close=_closedOut;
|
||||||
_closedIn=true;
|
_closedIn=true;
|
||||||
closed=_closeCode==0;
|
tell_app=_closeCode==0;
|
||||||
if (closed)
|
if (tell_app)
|
||||||
{
|
{
|
||||||
_closeCode=code;
|
_closeCode=code;
|
||||||
_closeMessage=message;
|
_closeMessage=message;
|
||||||
@ -318,14 +316,14 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (closed)
|
if (tell_app)
|
||||||
_webSocket.onClose(code,message);
|
_webSocket.onClose(code,message);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (closedOut)
|
if (close)
|
||||||
_endp.close();
|
_endp.close();
|
||||||
else
|
else
|
||||||
closeOut(code,message);
|
closeOut(code,message);
|
||||||
@ -343,13 +341,15 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||||||
LOG.debug("ClosedOut {} {}",this,message);
|
LOG.debug("ClosedOut {} {}",this,message);
|
||||||
|
|
||||||
final boolean close;
|
final boolean close;
|
||||||
final boolean closed;
|
final boolean tell_app;
|
||||||
|
final boolean send_close;
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
close=_closedIn || _closedOut;
|
close=_closedIn;
|
||||||
|
send_close=!_closedOut;
|
||||||
_closedOut=true;
|
_closedOut=true;
|
||||||
closed=_closeCode==0;
|
tell_app=_closeCode==0;
|
||||||
if (closed)
|
if (tell_app)
|
||||||
{
|
{
|
||||||
_closeCode=code;
|
_closeCode=code;
|
||||||
_closeMessage=message;
|
_closeMessage=message;
|
||||||
@ -358,16 +358,14 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (closed)
|
if (tell_app)
|
||||||
_webSocket.onClose(code,message);
|
_webSocket.onClose(code,message);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (close)
|
if (send_close)
|
||||||
_endp.close();
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (code<=0)
|
if (code<=0)
|
||||||
code=WebSocketConnectionD13.CLOSE_NORMAL;
|
code=WebSocketConnectionD13.CLOSE_NORMAL;
|
||||||
@ -375,8 +373,12 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||||||
bytes[0]=(byte)(code/0x100);
|
bytes[0]=(byte)(code/0x100);
|
||||||
bytes[1]=(byte)(code%0x100);
|
bytes[1]=(byte)(code%0x100);
|
||||||
_outbound.addFrame((byte)FLAG_FIN,WebSocketConnectionD13.OP_CLOSE,bytes,0,bytes.length);
|
_outbound.addFrame((byte)FLAG_FIN,WebSocketConnectionD13.OP_CLOSE,bytes,0,bytes.length);
|
||||||
}
|
|
||||||
_outbound.flush();
|
_outbound.flush();
|
||||||
|
if (close)
|
||||||
|
_endp.shutdownOutput();
|
||||||
|
}
|
||||||
|
else if (close)
|
||||||
|
_endp.close();
|
||||||
|
|
||||||
}
|
}
|
||||||
catch(IOException e)
|
catch(IOException e)
|
||||||
@ -712,7 +714,7 @@ public class WebSocketConnectionD13 extends AbstractConnection implements WebSoc
|
|||||||
String message=null;
|
String message=null;
|
||||||
if (buffer.length()>=2)
|
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)
|
if (buffer.length()>2)
|
||||||
message=new String(buffer.array(),buffer.getIndex()+2,buffer.length()-2,StringUtil.__UTF8);
|
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)
|
catch(ThreadDeath th)
|
||||||
{
|
{
|
||||||
throw 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
|
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");
|
String key = request.getHeader("Sec-WebSocket-Key");
|
||||||
|
|
||||||
response.setHeader("Upgrade","WebSocket");
|
response.setHeader("Upgrade","WebSocket");
|
||||||
|
@ -20,7 +20,6 @@ import java.util.Enumeration;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
@ -43,16 +42,19 @@ public class WebSocketFactory
|
|||||||
{
|
{
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
* @param request
|
* <p>Factory method that applications needs to implement to return a
|
||||||
* @param protocol
|
* {@link WebSocket} object.</p>
|
||||||
* @returns
|
* @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);
|
WebSocket doWebSocketConnect(HttpServletRequest request, String protocol);
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** Check the origin of an incoming WebSocket handshake request
|
/**
|
||||||
* @param request
|
* <p>Checks the origin of an incoming WebSocket handshake request.</p>
|
||||||
* @param origin
|
* @param request the incoming HTTP upgrade request
|
||||||
|
* @param origin the origin URI
|
||||||
* @return boolean to indicate that the origin is acceptable.
|
* @return boolean to indicate that the origin is acceptable.
|
||||||
*/
|
*/
|
||||||
boolean checkOrigin(HttpServletRequest request, String origin);
|
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
|
* Set the initial maximum binary message size for a connection. This can be changed by
|
||||||
* the application calling {@link WebSocket.Connection#setMaxBinaryMessageSize(int)}.
|
* 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)
|
public void setMaxBinaryMessageSize(int maxBinaryMessageSize)
|
||||||
{
|
{
|
||||||
|
@ -149,8 +149,6 @@ public class WebSocketGeneratorD00 implements WebSocketGenerator
|
|||||||
{
|
{
|
||||||
while (_buffer.space()==0)
|
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);
|
boolean ready = _endp.blockWritable(blockFor);
|
||||||
if (!ready)
|
if (!ready)
|
||||||
throw new IOException("Write timeout");
|
throw new IOException("Write timeout");
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
package org.eclipse.jetty.websocket;
|
package org.eclipse.jetty.websocket;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.SecureRandom;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.io.Buffer;
|
import org.eclipse.jetty.io.Buffer;
|
||||||
import org.eclipse.jetty.io.EndPoint;
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
@ -100,10 +98,10 @@ public class WebSocketGeneratorD06 implements WebSocketGenerator
|
|||||||
bufferPut(new byte[]{
|
bufferPut(new byte[]{
|
||||||
opcode,
|
opcode,
|
||||||
(byte)0x7f,
|
(byte)0x7f,
|
||||||
(byte)((payload>>56)&0x7f),
|
(byte)0,
|
||||||
(byte)((payload>>48)&0xff),
|
(byte)0,
|
||||||
(byte)((payload>>40)&0xff),
|
(byte)0,
|
||||||
(byte)((payload>>32)&0xff),
|
(byte)0,
|
||||||
(byte)((payload>>24)&0xff),
|
(byte)((payload>>24)&0xff),
|
||||||
(byte)((payload>>16)&0xff),
|
(byte)((payload>>16)&0xff),
|
||||||
(byte)((payload>>8)&0xff),
|
(byte)((payload>>8)&0xff),
|
||||||
@ -212,8 +210,6 @@ public class WebSocketGeneratorD06 implements WebSocketGenerator
|
|||||||
{
|
{
|
||||||
while (_buffer.space()==0)
|
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);
|
boolean ready = _endp.blockWritable(blockFor);
|
||||||
if (!ready)
|
if (!ready)
|
||||||
throw new IOException("Write timeout");
|
throw new IOException("Write timeout");
|
||||||
|
@ -66,7 +66,6 @@ public class WebSocketGeneratorD12 implements WebSocketGenerator
|
|||||||
_buffer=mask?_buffers.getBuffer():_buffers.getDirectBuffer();
|
_buffer=mask?_buffers.getBuffer():_buffers.getDirectBuffer();
|
||||||
|
|
||||||
boolean last=WebSocketConnectionD12.isLastFrame(flags);
|
boolean last=WebSocketConnectionD12.isLastFrame(flags);
|
||||||
byte orig=opcode;
|
|
||||||
|
|
||||||
int space=mask?14:10;
|
int space=mask?14:10;
|
||||||
|
|
||||||
@ -100,10 +99,10 @@ public class WebSocketGeneratorD12 implements WebSocketGenerator
|
|||||||
_buffer.put(new byte[]{
|
_buffer.put(new byte[]{
|
||||||
opcode,
|
opcode,
|
||||||
mask?(byte)0xff:(byte)0x7f,
|
mask?(byte)0xff:(byte)0x7f,
|
||||||
(byte)((payload>>56)&0x7f),
|
(byte)0,
|
||||||
(byte)((payload>>48)&0xff),
|
(byte)0,
|
||||||
(byte)((payload>>40)&0xff),
|
(byte)0,
|
||||||
(byte)((payload>>32)&0xff),
|
(byte)0,
|
||||||
(byte)((payload>>24)&0xff),
|
(byte)((payload>>24)&0xff),
|
||||||
(byte)((payload>>16)&0xff),
|
(byte)((payload>>16)&0xff),
|
||||||
(byte)((payload>>8)&0xff),
|
(byte)((payload>>8)&0xff),
|
||||||
|
@ -66,7 +66,6 @@ public class WebSocketGeneratorD13 implements WebSocketGenerator
|
|||||||
_buffer=mask?_buffers.getBuffer():_buffers.getDirectBuffer();
|
_buffer=mask?_buffers.getBuffer():_buffers.getDirectBuffer();
|
||||||
|
|
||||||
boolean last=WebSocketConnectionD13.isLastFrame(flags);
|
boolean last=WebSocketConnectionD13.isLastFrame(flags);
|
||||||
byte orig=opcode;
|
|
||||||
|
|
||||||
int space=mask?14:10;
|
int space=mask?14:10;
|
||||||
|
|
||||||
@ -100,10 +99,10 @@ public class WebSocketGeneratorD13 implements WebSocketGenerator
|
|||||||
_buffer.put(new byte[]{
|
_buffer.put(new byte[]{
|
||||||
opcode,
|
opcode,
|
||||||
mask?(byte)0xff:(byte)0x7f,
|
mask?(byte)0xff:(byte)0x7f,
|
||||||
(byte)((payload>>56)&0x7f),
|
(byte)0,
|
||||||
(byte)((payload>>48)&0xff),
|
(byte)0,
|
||||||
(byte)((payload>>40)&0xff),
|
(byte)0,
|
||||||
(byte)((payload>>32)&0xff),
|
(byte)0,
|
||||||
(byte)((payload>>24)&0xff),
|
(byte)((payload>>24)&0xff),
|
||||||
(byte)((payload>>16)&0xff),
|
(byte)((payload>>16)&0xff),
|
||||||
(byte)((payload>>8)&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.
|
* @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
|
* This should be a direct buffer if binary data is mostly used or an indirect buffer if utf-8 data
|
||||||
* is mostly used.
|
* is mostly used.
|
||||||
* @param endp
|
* @param endp the endpoint
|
||||||
* @param handler
|
* @param handler the handler to notify when a parse event occurs
|
||||||
*/
|
*/
|
||||||
public WebSocketParserD00(WebSocketBuffers buffers, EndPoint endp, FrameHandler handler)
|
public WebSocketParserD00(WebSocketBuffers buffers, EndPoint endp, FrameHandler handler)
|
||||||
{
|
{
|
||||||
@ -89,7 +89,6 @@ public class WebSocketParserD00 implements WebSocketParser
|
|||||||
int total_filled=0;
|
int total_filled=0;
|
||||||
|
|
||||||
// Loop until an datagram call back or can't fill anymore
|
// Loop until an datagram call back or can't fill anymore
|
||||||
boolean progress=true;
|
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
int length=_buffer.length();
|
int length=_buffer.length();
|
||||||
|
@ -47,7 +47,7 @@ public class WebSocketParserD06 implements WebSocketParser
|
|||||||
{
|
{
|
||||||
return _needs;
|
return _needs;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
private final WebSocketBuffers _buffers;
|
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.
|
* @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
|
* This should be a direct buffer if binary data is mostly used or an indirect buffer if utf-8 data
|
||||||
* is mostly used.
|
* is mostly used.
|
||||||
* @param endp
|
* @param endp the endpoint
|
||||||
* @param handler
|
* @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)
|
public WebSocketParserD06(WebSocketBuffers buffers, EndPoint endp, FrameHandler handler, boolean masked)
|
||||||
{
|
{
|
||||||
|
@ -47,7 +47,7 @@ public class WebSocketParserD12 implements WebSocketParser
|
|||||||
{
|
{
|
||||||
return _needs;
|
return _needs;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
private final WebSocketBuffers _buffers;
|
private final WebSocketBuffers _buffers;
|
||||||
private final EndPoint _endp;
|
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.
|
* @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
|
* This should be a direct buffer if binary data is mostly used or an indirect buffer if utf-8 data
|
||||||
* is mostly used.
|
* is mostly used.
|
||||||
* @param endp
|
* @param endp the endpoint
|
||||||
* @param handler
|
* @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)
|
public WebSocketParserD12(WebSocketBuffers buffers, EndPoint endp, FrameHandler handler, boolean shouldBeMasked)
|
||||||
{
|
{
|
||||||
|
@ -47,7 +47,7 @@ public class WebSocketParserD13 implements WebSocketParser
|
|||||||
{
|
{
|
||||||
return _needs;
|
return _needs;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
private final WebSocketBuffers _buffers;
|
private final WebSocketBuffers _buffers;
|
||||||
private final EndPoint _endp;
|
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.
|
* @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
|
* This should be a direct buffer if binary data is mostly used or an indirect buffer if utf-8 data
|
||||||
* is mostly used.
|
* is mostly used.
|
||||||
* @param endp
|
* @param endp the endpoint
|
||||||
* @param handler
|
* @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)
|
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();
|
Socket socket = _server.accept();
|
||||||
accept(socket);
|
accept(socket);
|
||||||
|
@ -909,6 +909,98 @@ public class WebSocketMessageD13Test
|
|||||||
lookFor("Message size > 15",input);
|
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
|
@Test
|
||||||
public void testMaxBinarySize2() throws Exception
|
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
|
private class Handler implements WebSocketParser.FrameHandler
|
||||||
{
|
{
|
||||||
public List<String> _data = new ArrayList<String>();
|
public List<String> _data = new ArrayList<String>();
|
||||||
|
@ -242,6 +242,7 @@ public abstract class ContinuationBase extends TestCase
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Socket socket = new Socket("localhost",port);
|
Socket socket = new Socket("localhost",port);
|
||||||
|
socket.setSoTimeout(10000);
|
||||||
socket.getOutputStream().write(request.getBytes("UTF-8"));
|
socket.getOutputStream().write(request.getBytes("UTF-8"));
|
||||||
|
|
||||||
response = toString(socket.getInputStream());
|
response = toString(socket.getInputStream());
|
||||||
|
@ -173,7 +173,7 @@
|
|||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-websocket</artifactId>
|
<artifactId>jetty-websocket</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>provided</scope>
|
<!--scope>provided</scope-->
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<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();
|
return new HashSessionIdManager();
|
||||||
}
|
}
|
||||||
|
@ -22,22 +22,29 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
|||||||
public class JdbcTestServer extends AbstractTestServer
|
public class JdbcTestServer extends AbstractTestServer
|
||||||
{
|
{
|
||||||
public static final String DRIVER_CLASS = "org.apache.derby.jdbc.EmbeddedDriver";
|
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;
|
public static final int SAVE_INTERVAL = 1;
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
System.setProperty("derby.system.home", MavenTestingUtils.getTargetFile("test-derby").getAbsolutePath());
|
System.setProperty("derby.system.home", MavenTestingUtils.getTargetFile("test-derby").getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public JdbcTestServer(int port)
|
public JdbcTestServer(int port)
|
||||||
{
|
{
|
||||||
super(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)
|
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)
|
public JdbcTestServer (int port, boolean optimize)
|
||||||
@ -60,14 +67,14 @@ public class JdbcTestServer extends AbstractTestServer
|
|||||||
* @see org.eclipse.jetty.server.session.AbstractTestServer#newSessionIdManager()
|
* @see org.eclipse.jetty.server.session.AbstractTestServer#newSessionIdManager()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public SessionIdManager newSessionIdManager()
|
public SessionIdManager newSessionIdManager(String config)
|
||||||
{
|
{
|
||||||
synchronized(JdbcTestServer.class)
|
synchronized(JdbcTestServer.class)
|
||||||
{
|
{
|
||||||
JDBCSessionIdManager idManager = new JDBCSessionIdManager(_server);
|
JDBCSessionIdManager idManager = new JDBCSessionIdManager(_server);
|
||||||
idManager.setScavengeInterval(_scavengePeriod);
|
idManager.setScavengeInterval(_scavengePeriod);
|
||||||
idManager.setWorkerName("w"+(__workers++));
|
idManager.setWorkerName("w"+(__workers++));
|
||||||
idManager.setDriverInfo(DRIVER_CLASS, CONNECTION_URL);
|
idManager.setDriverInfo(DRIVER_CLASS, (config==null?DEFAULT_CONNECTION_URL:config));
|
||||||
return idManager;
|
return idManager;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,16 @@ package org.eclipse.jetty.server.session;
|
|||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.EventListener;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpSession;
|
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.ContentExchange;
|
||||||
import org.eclipse.jetty.client.HttpClient;
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
@ -30,6 +34,8 @@ public abstract class AbstractRemoveSessionTest
|
|||||||
AbstractTestServer server = createServer(0, 1, scavengePeriod);
|
AbstractTestServer server = createServer(0, 1, scavengePeriod);
|
||||||
ServletContextHandler context = server.addContext(contextPath);
|
ServletContextHandler context = server.addContext(contextPath);
|
||||||
context.addServlet(TestServlet.class, servletMapping);
|
context.addServlet(TestServlet.class, servletMapping);
|
||||||
|
TestEventListener testListener = new TestEventListener();
|
||||||
|
context.getSessionHandler().addEventListener(testListener);
|
||||||
server.start();
|
server.start();
|
||||||
int port = server.getPort();
|
int port = server.getPort();
|
||||||
try
|
try
|
||||||
@ -49,6 +55,8 @@ public abstract class AbstractRemoveSessionTest
|
|||||||
assertTrue(sessionCookie != null);
|
assertTrue(sessionCookie != null);
|
||||||
// Mangle the cookie, replacing Path with $Path, etc.
|
// Mangle the cookie, replacing Path with $Path, etc.
|
||||||
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
|
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
|
||||||
|
//ensure sessionCreated listener is called
|
||||||
|
assertTrue (testListener.isCreated());
|
||||||
|
|
||||||
//now delete the session
|
//now delete the session
|
||||||
exchange = new ContentExchange(true);
|
exchange = new ContentExchange(true);
|
||||||
@ -58,6 +66,8 @@ public abstract class AbstractRemoveSessionTest
|
|||||||
client.send(exchange);
|
client.send(exchange);
|
||||||
exchange.waitForDone();
|
exchange.waitForDone();
|
||||||
assertEquals(HttpServletResponse.SC_OK,exchange.getResponseStatus());
|
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
|
// 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 final ContextHandlerCollection _contexts;
|
||||||
protected SessionIdManager _sessionIdManager;
|
protected SessionIdManager _sessionIdManager;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public AbstractTestServer(int port)
|
public AbstractTestServer(int port)
|
||||||
{
|
{
|
||||||
this(port, 30, 10);
|
this(port, 30, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractTestServer(int port, int maxInactivePeriod, int scavengePeriod)
|
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);
|
_server = new Server(port);
|
||||||
_maxInactivePeriod = maxInactivePeriod;
|
_maxInactivePeriod = maxInactivePeriod;
|
||||||
_scavengePeriod = scavengePeriod;
|
_scavengePeriod = scavengePeriod;
|
||||||
_contexts = new ContextHandlerCollection();
|
_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 SessionManager newSessionManager();
|
||||||
public abstract SessionHandler newSessionHandler(SessionManager sessionManager);
|
public abstract SessionHandler newSessionHandler(SessionManager sessionManager);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user