Updating rest for websocket-api

This commit is contained in:
Joakim Erdfelt 2012-11-05 12:01:42 -07:00
parent eb2e42d402
commit c1ce7780a6
166 changed files with 1471 additions and 3183 deletions

View File

@ -1,66 +0,0 @@
<?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>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-parent</artifactId>
<version>9.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.eclipse.jetty.drafts</groupId>
<artifactId>javax-websocket-api</artifactId>
<version>0.0.006.EDR</version>
<name>Jetty :: JSR-356 JavaWebSocket API</name>
<properties>
<bundle-symbolic-name>javax.net.websocket</bundle-symbolic-name>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
<verbose>false</verbose>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>ban-java-servlet-api</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedDependencies>
<includes>
<include>javax.servlet</include>
<include>servletapi</include>
<include>org.eclipse.jetty.orbit:javax.servlet</include>
<include>org.mortbay.jetty:servlet-api</include>
<include>jetty:servlet-api</include>
</includes>
</bannedDependencies>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -13,7 +13,6 @@
<packaging>pom</packaging>
<modules>
<module>javax-websocket-api</module>
<module>websocket-common</module>
<module>websocket-api</module>
<module>websocket-client</module>

View File

@ -1,5 +1,6 @@
<?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">
<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>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-parent</artifactId>
@ -15,6 +16,11 @@
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.protocol;
package org.eclipse.jetty.websocket.common;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.protocol;
package org.eclipse.jetty.websocket.common;
import java.nio.ByteBuffer;
@ -26,9 +26,10 @@ import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception;
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.core.api.BadPayloadException;
import org.eclipse.jetty.websocket.core.api.ProtocolException;
import org.eclipse.jetty.websocket.core.api.StatusCode;
import org.eclipse.jetty.websocket.api.BadPayloadException;
import org.eclipse.jetty.websocket.api.ProtocolException;
import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.api.extensions.Frame;
public class CloseInfo
{
@ -107,6 +108,16 @@ public class CloseInfo
}
}
public CloseInfo(Frame frame)
{
this(frame.getPayload(),false);
}
public CloseInfo(Frame frame, boolean validate)
{
this(frame.getPayload(),validate);
}
public CloseInfo(int statusCode)
{
this(statusCode, null);
@ -118,16 +129,6 @@ public class CloseInfo
this.reason = reason;
}
public CloseInfo(WebSocketFrame frame)
{
this(frame.getPayload(),false);
}
public CloseInfo(WebSocketFrame frame, boolean validate)
{
this(frame.getPayload(),validate);
}
public ByteBuffer asByteBuffer()
{
if ((statusCode == StatusCode.NO_CLOSE) || (statusCode == StatusCode.NO_CODE) || (statusCode == (-1)))

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.protocol;
package org.eclipse.jetty.websocket.common;
/**
* Connection states as outlined in <a href="https://tools.ietf.org/html/rfc6455">RFC6455</a>.

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.protocol;
package org.eclipse.jetty.websocket.common;
import java.nio.ByteBuffer;
import java.util.List;
@ -25,10 +25,10 @@ import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.api.Extension;
import org.eclipse.jetty.websocket.core.api.ProtocolException;
import org.eclipse.jetty.websocket.core.api.WebSocketBehavior;
import org.eclipse.jetty.websocket.core.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.api.ProtocolException;
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.common.extensions.AbstractExtension;
/**
* Generating a frame in WebSocket land.
@ -166,7 +166,7 @@ public class Generator
}
public void configureFromExtensions(List<? extends Extension> exts)
public void configureFromExtensions(List<? extends AbstractExtension> exts)
{
// default
this.rsv1InUse = false;
@ -174,7 +174,7 @@ public class Generator
this.rsv3InUse = false;
// configure from list of extensions in use
for(Extension ext: exts)
for(AbstractExtension ext: exts)
{
if (ext.isRsv1User())
{

View File

@ -16,13 +16,13 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
package org.eclipse.jetty.websocket.common;
import java.net.InetSocketAddress;
import org.eclipse.jetty.websocket.core.io.OutgoingFrames;
import org.eclipse.jetty.websocket.core.protocol.CloseInfo;
import org.eclipse.jetty.websocket.core.protocol.ConnectionState;
import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.api.SuspendToken;
import org.eclipse.jetty.websocket.common.io.OutgoingFrames;
public interface LogicalConnection extends OutgoingFrames
{

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.protocol;
package org.eclipse.jetty.websocket.common;
public final class OpCode
{

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.protocol;
package org.eclipse.jetty.websocket.common;
import java.nio.ByteBuffer;
import java.util.List;
@ -24,17 +24,17 @@ import java.util.List;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.api.Extension;
import org.eclipse.jetty.websocket.core.api.MessageTooLargeException;
import org.eclipse.jetty.websocket.core.api.ProtocolException;
import org.eclipse.jetty.websocket.core.api.WebSocketException;
import org.eclipse.jetty.websocket.core.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.core.io.IncomingFrames;
import org.eclipse.jetty.websocket.core.io.payload.CloseReasonValidator;
import org.eclipse.jetty.websocket.core.io.payload.DeMaskProcessor;
import org.eclipse.jetty.websocket.core.io.payload.NoOpValidator;
import org.eclipse.jetty.websocket.core.io.payload.PayloadProcessor;
import org.eclipse.jetty.websocket.core.io.payload.UTF8Validator;
import org.eclipse.jetty.websocket.api.MessageTooLargeException;
import org.eclipse.jetty.websocket.api.ProtocolException;
import org.eclipse.jetty.websocket.api.WebSocketException;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.common.extensions.AbstractExtension;
import org.eclipse.jetty.websocket.common.io.IncomingFrames;
import org.eclipse.jetty.websocket.common.io.payload.CloseReasonValidator;
import org.eclipse.jetty.websocket.common.io.payload.DeMaskProcessor;
import org.eclipse.jetty.websocket.common.io.payload.NoOpValidator;
import org.eclipse.jetty.websocket.common.io.payload.PayloadProcessor;
import org.eclipse.jetty.websocket.common.io.payload.UTF8Validator;
/**
* Parsing of a frames in WebSocket land.
@ -115,7 +115,7 @@ public class Parser
}
}
public void configureFromExtensions(List<? extends Extension> exts)
public void configureFromExtensions(List<? extends AbstractExtension> exts)
{
// default
this.rsv1InUse = false;
@ -124,7 +124,7 @@ public class Parser
this.isTextFrameValidated = true;
// configure from list of extensions in use
for(Extension ext: exts)
for(AbstractExtension ext: exts)
{
if (ext.isRsv1User())
{

View File

@ -16,24 +16,25 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.protocol;
package org.eclipse.jetty.websocket.common;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.eclipse.jetty.util.QuotedStringTokenizer;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
/**
* Proposed interface for API (not yet settled)
*/
public class ExtensionConfig
public class RequestedExtensionConfig implements ExtensionConfig
{
public static ExtensionConfig parse(String parameterizedName)
{
QuotedStringTokenizer tok = new QuotedStringTokenizer(parameterizedName,";");
ExtensionConfig ext = new ExtensionConfig(tok.nextToken().trim());
RequestedExtensionConfig ext = new RequestedExtensionConfig(tok.nextToken().trim());
while (tok.hasMoreTokens())
{
@ -49,17 +50,19 @@ public class ExtensionConfig
private final String name;
private Map<String, String> parameters;
public ExtensionConfig(String name)
public RequestedExtensionConfig(String name)
{
this.name = name;
this.parameters = new HashMap<>();
}
@Override
public String getName()
{
return name;
}
@Override
public int getParameter(String key, int defValue)
{
String val = parameters.get(key);
@ -69,6 +72,7 @@ public class ExtensionConfig
return Integer.valueOf(val);
}
@Override
public String getParameter(String key, String defValue)
{
String val = parameters.get(key);
@ -78,6 +82,7 @@ public class ExtensionConfig
return val;
}
@Override
public String getParameterizedName()
{
StringBuilder str = new StringBuilder();
@ -89,6 +94,7 @@ public class ExtensionConfig
return str.toString();
}
@Override
public Set<String> getParameterKeys()
{
return parameters.keySet();
@ -98,17 +104,19 @@ public class ExtensionConfig
* Initialize the parameters on this config from the other configuration.
* @param other the other configuration.
*/
public void init(ExtensionConfig other)
public void init(RequestedExtensionConfig other)
{
this.parameters.clear();
this.parameters.putAll(other.parameters);
}
@Override
public void setParameter(String key, int value)
{
parameters.put(key,Integer.toString(value));
}
@Override
public void setParameter(String key, String value)
{
parameters.put(key,value);

View File

@ -16,13 +16,14 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.protocol;
package org.eclipse.jetty.websocket.common;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.websocket.core.api.ProtocolException;
import org.eclipse.jetty.websocket.api.ProtocolException;
import org.eclipse.jetty.websocket.api.extensions.Frame;
/**
* A Base Frame as seen in <a href="https://tools.ietf.org/html/rfc6455#section-5.2">RFC 6455. Sec 5.2</a>
@ -100,6 +101,7 @@ public class WebSocketFrame implements Frame
/** position of start of data within a fresh payload */
private int payloadStart = -1;
private Type type;
private boolean continuation = false;
private int continuationIndex = 0;
@ -120,6 +122,38 @@ public class WebSocketFrame implements Frame
this.opcode = opcode;
}
/**
* Copy constructor for the websocket frame.
*
* @param copy
* the websocket to copy.
*/
public WebSocketFrame(Frame frame)
{
if(frame instanceof WebSocketFrame) {
WebSocketFrame wsf = (WebSocketFrame)frame;
copy(wsf,wsf.data);
} else {
// Copy manually
fin = frame.isFin();
rsv1 = frame.isRsv1();
rsv2 = frame.isRsv2();
rsv3 = frame.isRsv3();
opcode = frame.getType().getOpCode();
type = frame.getType();
masked = frame.isMasked();
mask = null;
byte maskCopy[] = frame.getMask();
if (maskCopy != null)
{
mask = new byte[maskCopy.length];
System.arraycopy(maskCopy,0,mask,0,mask.length);
}
setPayload(frame.getPayload());
}
}
/**
* Copy constructor for the websocket frame.
* <p>
@ -130,26 +164,7 @@ public class WebSocketFrame implements Frame
*/
public WebSocketFrame(WebSocketFrame copy)
{
fin = copy.fin;
rsv1 = copy.rsv2;
rsv2 = copy.rsv2;
rsv3 = copy.rsv3;
opcode = copy.opcode;
masked = copy.masked;
mask = null;
if (copy.mask != null)
{
mask = new byte[copy.mask.length];
System.arraycopy(copy.mask,0,mask,0,mask.length);
}
payloadLength = copy.payloadLength;
payloadStart = copy.payloadStart;
if (copy.data != null) // deal with empty payloads
{
data = copy.data.slice();
}
continuationIndex = copy.continuationIndex;
continuation = copy.continuation;
copy(copy,copy.data);
}
/**
@ -164,21 +179,7 @@ public class WebSocketFrame implements Frame
*/
public WebSocketFrame(WebSocketFrame copy, ByteBuffer altPayload)
{
fin = copy.fin;
rsv1 = copy.rsv2;
rsv2 = copy.rsv2;
rsv3 = copy.rsv3;
opcode = copy.opcode;
masked = copy.masked;
mask = null;
if (copy.mask != null)
{
mask = new byte[copy.mask.length];
System.arraycopy(copy.mask,0,mask,0,mask.length);
}
continuationIndex = copy.continuationIndex;
continuation = copy.continuation;
setPayload(altPayload);
copy(copy,altPayload);
}
public void assertValid()
@ -218,6 +219,27 @@ public class WebSocketFrame implements Frame
}
}
private final void copy(WebSocketFrame copy, ByteBuffer payload)
{
fin = copy.fin;
rsv1 = copy.rsv1;
rsv2 = copy.rsv2;
rsv3 = copy.rsv3;
opcode = copy.opcode;
type = copy.type;
masked = copy.masked;
mask = null;
if (copy.mask != null)
{
mask = new byte[copy.mask.length];
System.arraycopy(copy.mask,0,mask,0,mask.length);
}
continuationIndex = copy.continuationIndex;
continuation = copy.continuation;
setPayload(payload);
}
/**
* The number of fragments this frame consists of.
* <p>
@ -242,7 +264,6 @@ public class WebSocketFrame implements Frame
return mask;
}
@Override
public final byte getOpCode()
{
return opcode;
@ -297,6 +318,12 @@ public class WebSocketFrame implements Frame
return payloadStart;
}
@Override
public Type getType()
{
return type;
}
public boolean hasPayload()
{
return ((data != null) && (payloadLength > 0));
@ -323,6 +350,12 @@ public class WebSocketFrame implements Frame
return fin;
}
@Override
public boolean isLast()
{
return fin;
}
public boolean isLastFrame()
{
return fin;
@ -433,6 +466,7 @@ public class WebSocketFrame implements Frame
public WebSocketFrame setOpCode(byte op)
{
this.opcode = op;
this.type = Frame.Type.from(op);
return this;
}

View File

@ -16,28 +16,19 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
import java.io.IOException;
package org.eclipse.jetty.websocket.common.extensions;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FutureCallback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.io.IncomingFrames;
import org.eclipse.jetty.websocket.core.io.OutgoingFrames;
import org.eclipse.jetty.websocket.core.protocol.ExtensionConfig;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.api.WebSocketConnection;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.api.extensions.Extension;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
public abstract class Extension implements OutgoingFrames, IncomingFrames
public abstract class AbstractExtension implements Extension
{
private Logger LOG = Log.getLogger(this.getClass());
private WebSocketPolicy policy;
private ByteBufferPool bufferPool;
private ExtensionConfig config;
private IncomingFrames nextIncomingFrames;
private OutgoingFrames nextOutgoingFrames;
private WebSocketConnection connection;
public ByteBufferPool getBufferPool()
@ -45,6 +36,7 @@ public abstract class Extension implements OutgoingFrames, IncomingFrames
return bufferPool;
}
@Override
public ExtensionConfig getConfig()
{
return config;
@ -55,45 +47,17 @@ public abstract class Extension implements OutgoingFrames, IncomingFrames
return connection;
}
@Override
public String getName()
{
return config.getName();
}
public IncomingFrames getNextIncomingFrames()
{
return nextIncomingFrames;
}
public OutgoingFrames getNextOutgoingFrames()
{
return nextOutgoingFrames;
}
public String getParameterizedName()
{
return config.getParameterizedName();
}
public WebSocketPolicy getPolicy()
{
return policy;
}
@Override
public void incoming(WebSocketException e)
{
// pass thru, un-modified
nextIncoming(e);
}
@Override
public void incoming(WebSocketFrame frame)
{
// pass thru, un-modified
nextIncoming(frame);
}
/**
* Used to indicate that the extension makes use of the RSV1 bit of the base websocket framing.
* <p>
@ -146,67 +110,6 @@ public abstract class Extension implements OutgoingFrames, IncomingFrames
return false;
}
/**
* Convenience method for {@link #getNextIncomingFrames()#incoming(WebSocketException)}
*
* @param e
* the exception to pass to the next input/incoming
*/
public void nextIncoming(WebSocketException e)
{
if (LOG.isDebugEnabled())
{
LOG.debug("nextIncoming({}) - {}",e,nextIncomingFrames);
}
nextIncomingFrames.incoming(e);
}
/**
* Convenience method for {@link #getNextIncomingFrames()#incoming(WebSocketFrame)}
*
* @param frame
* the frame to send to the next input/incoming
*/
public void nextIncoming(WebSocketFrame frame)
{
if (LOG.isDebugEnabled())
{
LOG.debug("nextIncoming({}) - {}",frame,nextIncomingFrames);
}
nextIncomingFrames.incoming(frame);
}
/**
* Convenience method for {@link #getNextOutgoingFrames()#output(WebSocketFrame)}
*
* @param frame
* the frame to send to the next output
*/
public <C> void nextOutput(C context, Callback<C> callback, WebSocketFrame frame) throws IOException
{
if (LOG.isDebugEnabled())
{
LOG.debug("nextOutput({}) - {}",frame,nextOutgoingFrames);
}
nextOutgoingFrames.output(context,callback,frame);
}
public <C> void nextOutputNoCallback(WebSocketFrame frame) throws IOException
{
if (LOG.isDebugEnabled())
{
LOG.debug("nextOutput({}) - {}",frame,nextOutgoingFrames);
}
nextOutgoingFrames.output(null,new FutureCallback<Void>(),frame);
}
@Override
public <C> void output(C context, Callback<C> callback, WebSocketFrame frame) throws IOException
{
// pass thru, un-modified
nextOutput(context,callback,frame);
}
public void setBufferPool(ByteBufferPool bufferPool)
{
this.bufferPool = bufferPool;
@ -222,16 +125,6 @@ public abstract class Extension implements OutgoingFrames, IncomingFrames
this.connection = connection;
}
public void setNextIncomingFrames(IncomingFrames nextIncomingFramesHandler)
{
this.nextIncomingFrames = nextIncomingFramesHandler;
}
public void setNextOutgoingFrames(OutgoingFrames nextOutgoingFramesHandler)
{
this.nextOutgoingFrames = nextOutgoingFramesHandler;
}
public void setPolicy(WebSocketPolicy policy)
{
this.policy = policy;

View File

@ -0,0 +1,58 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.common.extensions;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.api.extensions.Frame;
import org.eclipse.jetty.websocket.api.extensions.FrameHandler;
import org.eclipse.jetty.websocket.api.extensions.FrameHandlerWrapper;
public abstract class FrameHandlerAdapter implements FrameHandlerWrapper
{
private Logger log;
private FrameHandler nextHandler;
public FrameHandlerAdapter()
{
log = Log.getLogger(this.getClass());
}
@Override
public FrameHandler getNextHandler()
{
return nextHandler;
}
protected void nextHandler(Frame frame)
{
if (log.isDebugEnabled())
{
log.debug("nextHandler({}) -> {}",frame,nextHandler);
}
nextHandler.handleFrame(frame);
}
@Override
public void setNextHandler(FrameHandler handler)
{
this.nextHandler = handler;
}
}

View File

@ -0,0 +1,83 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.common.extensions;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.websocket.api.WebSocketException;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.api.extensions.Extension;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
import org.eclipse.jetty.websocket.api.extensions.ExtensionRegistry;
public class WebSocketExtensionRegistry extends ExtensionRegistry
{
private WebSocketPolicy policy;
private ByteBufferPool bufferPool;
public WebSocketExtensionRegistry(WebSocketPolicy policy, ByteBufferPool bufferPool)
{
this.policy = policy;
this.bufferPool = bufferPool;
// FIXME this.registry.put("identity",IdentityExtension.class);
// FIXME this.registry.put("fragment",FragmentExtension.class);
// FIXME this.registry.put("x-webkit-deflate-frame",WebkitDeflateFrameExtension.class);
// FIXME this.registry.put("permessage-compress",PerMessageCompressionExtension.class);
}
public Extension newInstance(ExtensionConfig config)
{
if (config == null)
{
return null;
}
String name = config.getName();
if (StringUtil.isBlank(name))
{
return null;
}
Extension registeredExt = getExtension(name);
if (registeredExt == null)
{
return null;
}
Class<? extends Extension> extClass = registeredExt.getClass();
try
{
Extension ext = extClass.newInstance();
if (ext instanceof AbstractExtension)
{
AbstractExtension aext = (AbstractExtension)ext;
aext.setConfig(config);
aext.setPolicy(policy);
aext.setBufferPool(bufferPool);
}
return ext;
}
catch (InstantiationException | IllegalAccessException e)
{
throw new WebSocketException("Cannot instantiate extension: " + extClass,e);
}
}
}

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.compress;
package org.eclipse.jetty.websocket.common.extensions.compress;
import java.nio.ByteBuffer;

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.compress;
package org.eclipse.jetty.websocket.common.extensions.compress;
import java.nio.ByteBuffer;
import java.util.zip.DataFormatException;
@ -26,7 +26,7 @@ import java.util.zip.Inflater;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.api.BadPayloadException;
import org.eclipse.jetty.websocket.api.BadPayloadException;
/**
* Deflate Compression Method

View File

@ -0,0 +1,198 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.common.extensions.compress;
import java.nio.ByteBuffer;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
import org.eclipse.jetty.websocket.api.extensions.Frame;
import org.eclipse.jetty.websocket.api.extensions.FrameHandler;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.extensions.AbstractExtension;
import org.eclipse.jetty.websocket.common.extensions.FrameHandlerAdapter;
/**
* Per Message Compression extension for WebSocket.
* <p>
* Attempts to follow <a href="https://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-01">draft-ietf-hybi-permessage-compression-01</a>
*/
public class PerMessageCompressionExtension extends AbstractExtension
{
private static class CompressMessageHandler extends FrameHandlerAdapter
{
private final CompressionMethod method;
private final ByteBufferPool bufferPool;
public CompressMessageHandler(CompressionMethod method, ByteBufferPool bufferPool)
{
this.method = method;
this.bufferPool = bufferPool;
}
@Override
public void handleFrame(Frame frame)
{
if (frame instanceof Frame.Control)
{
// skip, cannot compress control frames.
nextHandler(frame);
return;
}
ByteBuffer data = frame.getPayload();
try
{
// deflate data
method.compress().input(data);
while (!method.compress().isDone())
{
ByteBuffer buf = method.compress().process();
WebSocketFrame out = new WebSocketFrame(frame).setPayload(buf);
out.setRsv1(true);
if (!method.compress().isDone())
{
out.setFin(false);
nextHandler(out);
}
else
{
nextHandler(out);
}
}
// reset only at end of message
if (frame.isFin())
{
method.compress().end();
}
}
finally
{
// free original data buffer
bufferPool.release(data);
}
}
}
private static class DecompressMessageHandler extends FrameHandlerAdapter
{
private CompressionMethod method;
private final ByteBufferPool bufferPool;
public DecompressMessageHandler(CompressionMethod method, ByteBufferPool bufferPool)
{
this.method = method;
this.bufferPool = bufferPool;
}
@Override
public void handleFrame(Frame frame)
{
if ((frame instanceof Frame.Control) || !frame.isRsv1())
{
// Cannot modify incoming control frames or ones with RSV1 set.
nextHandler(frame);
return;
}
ByteBuffer data = frame.getPayload();
try
{
method.decompress().input(data);
while (!method.decompress().isDone())
{
ByteBuffer uncompressed = method.decompress().process();
if (uncompressed == null)
{
continue;
}
WebSocketFrame out = new WebSocketFrame(frame).setPayload(uncompressed);
if (!method.decompress().isDone())
{
out.setFin(false);
}
nextHandler(out);
}
// reset only at the end of a message.
if (frame.isFin())
{
method.decompress().end();
}
}
finally
{
// release original buffer (no longer needed)
bufferPool.release(data);
}
}
}
private static final Logger LOG = Log.getLogger(PerMessageCompressionExtension.class);
private CompressionMethod method;
@Override
public FrameHandler createIncomingFrameHandler()
{
return new DecompressMessageHandler(method,getBufferPool());
}
@Override
public FrameHandler createOutgoingFrameHandler()
{
return new CompressMessageHandler(method,getBufferPool());
}
/**
* Indicates use of RSV1 flag for indicating deflation is in use.
*/
@Override
public boolean isRsv1User()
{
return true;
}
@Override
public boolean isTextDataDecoder()
{
// this extension is responsible for text data frames
return true;
}
@Override
public void setConfig(ExtensionConfig config)
{
super.setConfig(config);
String methodOptions = config.getParameter("method","deflate");
LOG.debug("Method requested: {}",methodOptions);
method = new DeflateCompressionMethod();
}
@Override
public String toString()
{
return String.format("%s[method=%s]",this.getClass().getSimpleName(),method);
}
}

View File

@ -0,0 +1,188 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.common.extensions.compress;
import java.nio.ByteBuffer;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
import org.eclipse.jetty.websocket.api.extensions.Frame;
import org.eclipse.jetty.websocket.api.extensions.FrameHandler;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.extensions.AbstractExtension;
import org.eclipse.jetty.websocket.common.extensions.FrameHandlerAdapter;
/**
* Implementation of the <a href="https://tools.ietf.org/id/draft-tyoshino-hybi-websocket-perframe-deflate-05.txt">x-webkit-deflate-frame</a> extension seen out
* in the wild.
*/
public class WebkitDeflateFrameExtension extends AbstractExtension
{
private static class CompressFrameHandler extends FrameHandlerAdapter
{
private final CompressionMethod method;
private final ByteBufferPool bufferPool;
public CompressFrameHandler(DeflateCompressionMethod method, ByteBufferPool bufferPool)
{
this.method = method;
this.bufferPool = bufferPool;
}
@Override
public void handleFrame(Frame frame)
{
if (frame instanceof Frame.Control)
{
// skip, cannot compress control frames.
nextHandler(frame);
return;
}
ByteBuffer data = frame.getPayload();
try
{
// deflate data
method.compress().input(data);
while (!method.compress().isDone())
{
ByteBuffer buf = method.compress().process();
WebSocketFrame out = new WebSocketFrame(frame).setPayload(buf);
out.setRsv1(true);
if (!method.compress().isDone())
{
out.setFin(false);
}
nextHandler(out);
}
// reset on every frame.
method.compress().end();
}
finally
{
// free original data buffer
bufferPool.release(data);
}
}
}
private static class DecompressFrameHandler extends FrameHandlerAdapter
{
private final CompressionMethod method;
private final ByteBufferPool bufferPool;
public DecompressFrameHandler(DeflateCompressionMethod method, ByteBufferPool bufferPool)
{
this.method = method;
this.bufferPool = bufferPool;
}
@Override
public void handleFrame(Frame frame)
{
if ((frame instanceof Frame.Control) || !frame.isRsv1())
{
// Cannot modify incoming control frames or ones with RSV1 set.
nextHandler(frame);
return;
}
LOG.debug("Decompressing Frame: {}",frame);
ByteBuffer data = frame.getPayload();
try
{
method.decompress().input(data);
while (!method.decompress().isDone())
{
ByteBuffer uncompressed = method.decompress().process();
WebSocketFrame out = new WebSocketFrame(frame).setPayload(uncompressed);
if (!method.decompress().isDone())
{
out.setFin(false);
}
nextHandler(out);
}
// reset on every frame.
method.decompress().end();
}
finally
{
// release original buffer (no longer needed)
bufferPool.release(data);
}
}
}
private static final Logger LOG = Log.getLogger(WebkitDeflateFrameExtension.class);
private DeflateCompressionMethod method;
@Override
public FrameHandler createIncomingFrameHandler()
{
return new DecompressFrameHandler(method,getBufferPool());
}
@Override
public FrameHandler createOutgoingFrameHandler()
{
return new CompressFrameHandler(method,getBufferPool());
}
/**
* Indicates use of RSV1 flag for indicating deflation is in use.
* <p>
* Also known as the "COMP" framing header bit
*/
@Override
public boolean isRsv1User()
{
return true;
}
/**
* Indicate that this extensions is now responsible for TEXT Data Frame compliance to the WebSocket spec.
*/
@Override
public boolean isTextDataDecoder()
{
return true;
}
@Override
public void setConfig(ExtensionConfig config)
{
super.setConfig(config);
method = new DeflateCompressionMethod();
}
@Override
public String toString()
{
return this.getClass().getSimpleName() + "[]";
}
}

View File

@ -0,0 +1,117 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.common.extensions.fragment;
import java.nio.ByteBuffer;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
import org.eclipse.jetty.websocket.api.extensions.Frame;
import org.eclipse.jetty.websocket.api.extensions.FrameHandler;
import org.eclipse.jetty.websocket.common.OpCode;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.extensions.AbstractExtension;
import org.eclipse.jetty.websocket.common.extensions.FrameHandlerAdapter;
public class FragmentExtension extends AbstractExtension
{
/**
* Handler to break apart the frames into multiple smaller frames.
*/
private class FragmentHandler extends FrameHandlerAdapter
{
@Override
public void handleFrame(Frame frame)
{
if (frame instanceof Frame.Control)
{
// Cannot fragment Control Frames
nextHandler(frame);
return;
}
int length = frame.getPayloadLength();
byte opcode = frame.getOpCode(); // original opcode
ByteBuffer payload = frame.getPayload().slice();
int originalLimit = payload.limit();
int currentPosition = payload.position();
if (maxLength <= 0)
{
// output original frame
nextHandler(frame);
return;
}
boolean continuation = false;
// break apart payload based on maxLength rules
while (length > maxLength)
{
WebSocketFrame frag = new WebSocketFrame(frame);
frag.setOpCode(opcode);
frag.setFin(false); // always false here
frag.setContinuation(continuation);
payload.position(currentPosition);
payload.limit(Math.min(payload.position() + maxLength,originalLimit));
frag.setPayload(payload);
nextHandler(frag);
length -= maxLength;
opcode = OpCode.CONTINUATION;
continuation = true;
currentPosition = payload.limit();
}
// write remaining
WebSocketFrame frag = new WebSocketFrame(frame);
frag.setOpCode(opcode);
frag.setFin(frame.isFin()); // use original fin
frag.setContinuation(continuation);
payload.position(currentPosition);
payload.limit(originalLimit);
frag.setPayload(payload);
nextHandler(frag);
}
}
private int maxLength = -1;
@Override
public FrameHandler createIncomingFrameHandler()
{
return new FragmentHandler();
}
@Override
public FrameHandler createOutgoingFrameHandler()
{
return new FragmentHandler();
}
@Override
public void setConfig(ExtensionConfig config)
{
super.setConfig(config);
maxLength = config.getParameter("maxLength",maxLength);
}
}

View File

@ -16,16 +16,29 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.identity;
package org.eclipse.jetty.websocket.common.extensions.identity;
import org.eclipse.jetty.util.QuotedStringTokenizer;
import org.eclipse.jetty.websocket.core.api.Extension;
import org.eclipse.jetty.websocket.core.protocol.ExtensionConfig;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
import org.eclipse.jetty.websocket.api.extensions.FrameHandler;
import org.eclipse.jetty.websocket.common.extensions.AbstractExtension;
public class IdentityExtension extends Extension
public class IdentityExtension extends AbstractExtension
{
private String id;
@Override
public FrameHandler createIncomingFrameHandler()
{
return new IdentityFrameHandler();
}
@Override
public FrameHandler createOutgoingFrameHandler()
{
return new IdentityFrameHandler();
}
@Override
public void setConfig(ExtensionConfig config)
{

View File

@ -16,18 +16,19 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
package org.eclipse.jetty.websocket.common.extensions.identity;
import java.util.Iterator;
import org.eclipse.jetty.websocket.api.extensions.Frame;
import org.eclipse.jetty.websocket.common.extensions.FrameHandlerAdapter;
public interface ExtensionRegistry extends Iterable<Class<? extends Extension>>
/**
* FrameHandler that just passes frames through with no modification.
*/
public class IdentityFrameHandler extends FrameHandlerAdapter
{
public boolean isAvailable(String name);
@Override
public Iterator<Class<? extends Extension>> iterator();
public void register(String name, Class<? extends Extension> extension);
public void unregister(String name);
public void handleFrame(Frame frame)
{
nextHandler(frame);
}
}

View File

@ -16,20 +16,20 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux;
package org.eclipse.jetty.websocket.common.extensions.mux;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.websocket.core.api.Extension;
import org.eclipse.jetty.websocket.core.api.WebSocketConnection;
import org.eclipse.jetty.websocket.core.api.WebSocketException;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.api.WebSocketConnection;
import org.eclipse.jetty.websocket.api.WebSocketException;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.extensions.AbstractExtension;
/**
* Multiplexing Extension for WebSockets.
* <p>
* Supporting <a href="https://tools.ietf.org/html/draft-ietf-hybi-websocket-multiplexing-08">draft-ietf-hybi-websocket-multiplexing-08</a> Specification.
*/
public abstract class AbstractMuxExtension extends Extension
public abstract class AbstractMuxExtension extends AbstractExtension
{
private Muxer muxer;

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux;
package org.eclipse.jetty.websocket.common.extensions.mux;
import java.io.IOException;
import java.net.InetSocketAddress;
@ -30,19 +30,19 @@ import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FutureCallback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.api.Extension;
import org.eclipse.jetty.websocket.core.api.StatusCode;
import org.eclipse.jetty.websocket.core.api.SuspendToken;
import org.eclipse.jetty.websocket.core.api.WebSocketConnection;
import org.eclipse.jetty.websocket.core.api.WebSocketException;
import org.eclipse.jetty.websocket.core.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.core.io.IncomingFrames;
import org.eclipse.jetty.websocket.core.io.InternalConnection;
import org.eclipse.jetty.websocket.core.io.OutgoingFrames;
import org.eclipse.jetty.websocket.core.io.WebSocketSession;
import org.eclipse.jetty.websocket.core.protocol.CloseInfo;
import org.eclipse.jetty.websocket.core.protocol.ConnectionState;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.api.SuspendToken;
import org.eclipse.jetty.websocket.api.WebSocketConnection;
import org.eclipse.jetty.websocket.api.WebSocketException;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.common.CloseInfo;
import org.eclipse.jetty.websocket.common.ConnectionState;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.extensions.AbstractExtension;
import org.eclipse.jetty.websocket.common.io.IncomingFrames;
import org.eclipse.jetty.websocket.common.io.InternalConnection;
import org.eclipse.jetty.websocket.common.io.OutgoingFrames;
import org.eclipse.jetty.websocket.common.io.WebSocketSession;
/**
* MuxChannel, acts as WebSocketConnection for specific sub-channel.
@ -97,7 +97,7 @@ public class MuxChannel implements WebSocketConnection, InternalConnection, Inco
}
@Override
public void configureFromExtensions(List<Extension> extensions)
public void configureFromExtensions(List<AbstractExtension> extensions)
{
/* ignore */
}
@ -284,7 +284,7 @@ public class MuxChannel implements WebSocketConnection, InternalConnection, Inco
return this;
}
public void wireUpExtensions(List<Extension> extensions)
public void wireUpExtensions(List<AbstractExtension> extensions)
{
// Start with default routing.
incoming = session;
@ -292,12 +292,12 @@ public class MuxChannel implements WebSocketConnection, InternalConnection, Inco
if (extensions != null)
{
Iterator<Extension> extIter;
Iterator<AbstractExtension> extIter;
// Connect outgoings
extIter = extensions.iterator();
while (extIter.hasNext())
{
Extension ext = extIter.next();
AbstractExtension ext = extIter.next();
ext.setNextOutgoingFrames(outgoing);
outgoing = ext;
}
@ -307,7 +307,7 @@ public class MuxChannel implements WebSocketConnection, InternalConnection, Inco
extIter = extensions.iterator();
while (extIter.hasNext())
{
Extension ext = extIter.next();
AbstractExtension ext = extIter.next();
ext.setNextIncomingFrames(incoming);
incoming = ext;
}

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux;
package org.eclipse.jetty.websocket.common.extensions.mux;
public interface MuxControlBlock
{

View File

@ -16,9 +16,9 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux;
package org.eclipse.jetty.websocket.common.extensions.mux;
import org.eclipse.jetty.websocket.core.api.WebSocketException;
import org.eclipse.jetty.websocket.api.WebSocketException;
@SuppressWarnings("serial")
public class MuxException extends WebSocketException

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux;
package org.eclipse.jetty.websocket.common.extensions.mux;
import java.io.IOException;
import java.nio.ByteBuffer;
@ -26,13 +26,13 @@ import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FutureCallback;
import org.eclipse.jetty.websocket.core.extensions.mux.op.MuxAddChannelRequest;
import org.eclipse.jetty.websocket.core.extensions.mux.op.MuxAddChannelResponse;
import org.eclipse.jetty.websocket.core.extensions.mux.op.MuxDropChannel;
import org.eclipse.jetty.websocket.core.extensions.mux.op.MuxFlowControl;
import org.eclipse.jetty.websocket.core.extensions.mux.op.MuxNewChannelSlot;
import org.eclipse.jetty.websocket.core.io.OutgoingFrames;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.extensions.mux.op.MuxAddChannelRequest;
import org.eclipse.jetty.websocket.common.extensions.mux.op.MuxAddChannelResponse;
import org.eclipse.jetty.websocket.common.extensions.mux.op.MuxDropChannel;
import org.eclipse.jetty.websocket.common.extensions.mux.op.MuxFlowControl;
import org.eclipse.jetty.websocket.common.extensions.mux.op.MuxNewChannelSlot;
import org.eclipse.jetty.websocket.common.io.OutgoingFrames;
/**
* Generate Mux frames destined for the physical connection.

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux;
package org.eclipse.jetty.websocket.common.extensions.mux;
public final class MuxOp
{

View File

@ -16,20 +16,20 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux;
package org.eclipse.jetty.websocket.common.extensions.mux;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.extensions.mux.op.MuxAddChannelRequest;
import org.eclipse.jetty.websocket.core.extensions.mux.op.MuxAddChannelResponse;
import org.eclipse.jetty.websocket.core.extensions.mux.op.MuxDropChannel;
import org.eclipse.jetty.websocket.core.extensions.mux.op.MuxFlowControl;
import org.eclipse.jetty.websocket.core.extensions.mux.op.MuxNewChannelSlot;
import org.eclipse.jetty.websocket.core.protocol.OpCode;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.common.OpCode;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.extensions.mux.op.MuxAddChannelRequest;
import org.eclipse.jetty.websocket.common.extensions.mux.op.MuxAddChannelResponse;
import org.eclipse.jetty.websocket.common.extensions.mux.op.MuxDropChannel;
import org.eclipse.jetty.websocket.common.extensions.mux.op.MuxFlowControl;
import org.eclipse.jetty.websocket.common.extensions.mux.op.MuxNewChannelSlot;
public class MuxParser
{

View File

@ -16,9 +16,9 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux;
package org.eclipse.jetty.websocket.common.extensions.mux;
import org.eclipse.jetty.websocket.core.extensions.mux.op.MuxDropChannel;
import org.eclipse.jetty.websocket.common.extensions.mux.op.MuxDropChannel;
public class MuxPhysicalConnectionException extends MuxException
{

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux;
package org.eclipse.jetty.websocket.common.extensions.mux;
import java.nio.ByteBuffer;
import java.util.List;
@ -24,8 +24,8 @@ import java.util.Map;
import org.eclipse.jetty.util.QuotedStringTokenizer;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.websocket.core.api.UpgradeRequest;
import org.eclipse.jetty.websocket.core.protocol.ExtensionConfig;
import org.eclipse.jetty.websocket.api.UpgradeRequest;
import org.eclipse.jetty.websocket.common.RequestedExtensionConfig;
public class MuxRequest implements UpgradeRequest
{
@ -64,7 +64,7 @@ public class MuxRequest implements UpgradeRequest
private String queryString;
private List<String> subProtocols;
private Map<String, String> cookies;
private List<ExtensionConfig> extensions;
private List<RequestedExtensionConfig> extensions;
private Map<String, List<String>> headers;
private Map<String, String[]> parameterMap;
@ -83,7 +83,7 @@ public class MuxRequest implements UpgradeRequest
{
for (String extConfig : extConfigs)
{
extensions.add(ExtensionConfig.parse(extConfig));
extensions.add(RequestedExtensionConfig.parse(extConfig));
}
}
@ -94,7 +94,7 @@ public class MuxRequest implements UpgradeRequest
}
@Override
public List<ExtensionConfig> getExtensions()
public List<RequestedExtensionConfig> getExtensions()
{
return extensions;
}

View File

@ -16,16 +16,16 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux;
package org.eclipse.jetty.websocket.common.extensions.mux;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.jetty.websocket.core.api.UpgradeException;
import org.eclipse.jetty.websocket.core.api.UpgradeResponse;
import org.eclipse.jetty.websocket.core.protocol.ExtensionConfig;
import org.eclipse.jetty.websocket.api.UpgradeException;
import org.eclipse.jetty.websocket.api.UpgradeResponse;
import org.eclipse.jetty.websocket.common.RequestedExtensionConfig;
public class MuxResponse implements UpgradeResponse
{
@ -43,7 +43,7 @@ public class MuxResponse implements UpgradeResponse
}
@Override
public List<ExtensionConfig> getExtensions()
public List<RequestedExtensionConfig> getExtensions()
{
// TODO Auto-generated method stub
return null;
@ -106,7 +106,7 @@ public class MuxResponse implements UpgradeResponse
}
@Override
public void setExtensions(List<ExtensionConfig> extensions)
public void setExtensions(List<RequestedExtensionConfig> extensions)
{
// TODO Auto-generated method stub

View File

@ -16,10 +16,10 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux;
package org.eclipse.jetty.websocket.common.extensions.mux;
import org.eclipse.jetty.websocket.core.protocol.OpCode;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.common.OpCode;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
public class MuxedFrame extends WebSocketFrame
{

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux;
package org.eclipse.jetty.websocket.common.extensions.mux;
import java.io.IOException;
import java.net.InetSocketAddress;
@ -28,22 +28,22 @@ import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.api.StatusCode;
import org.eclipse.jetty.websocket.core.api.UpgradeRequest;
import org.eclipse.jetty.websocket.core.api.WebSocketBehavior;
import org.eclipse.jetty.websocket.core.api.WebSocketConnection;
import org.eclipse.jetty.websocket.core.api.WebSocketException;
import org.eclipse.jetty.websocket.core.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.core.extensions.mux.add.MuxAddClient;
import org.eclipse.jetty.websocket.core.extensions.mux.add.MuxAddServer;
import org.eclipse.jetty.websocket.core.extensions.mux.op.MuxAddChannelRequest;
import org.eclipse.jetty.websocket.core.extensions.mux.op.MuxAddChannelResponse;
import org.eclipse.jetty.websocket.core.extensions.mux.op.MuxDropChannel;
import org.eclipse.jetty.websocket.core.extensions.mux.op.MuxFlowControl;
import org.eclipse.jetty.websocket.core.extensions.mux.op.MuxNewChannelSlot;
import org.eclipse.jetty.websocket.core.io.IncomingFrames;
import org.eclipse.jetty.websocket.core.io.OutgoingFrames;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.api.UpgradeRequest;
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
import org.eclipse.jetty.websocket.api.WebSocketConnection;
import org.eclipse.jetty.websocket.api.WebSocketException;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.extensions.mux.add.MuxAddClient;
import org.eclipse.jetty.websocket.common.extensions.mux.add.MuxAddServer;
import org.eclipse.jetty.websocket.common.extensions.mux.op.MuxAddChannelRequest;
import org.eclipse.jetty.websocket.common.extensions.mux.op.MuxAddChannelResponse;
import org.eclipse.jetty.websocket.common.extensions.mux.op.MuxDropChannel;
import org.eclipse.jetty.websocket.common.extensions.mux.op.MuxFlowControl;
import org.eclipse.jetty.websocket.common.extensions.mux.op.MuxNewChannelSlot;
import org.eclipse.jetty.websocket.common.io.IncomingFrames;
import org.eclipse.jetty.websocket.common.io.OutgoingFrames;
/**
* Muxer responsible for managing sub-channels.

View File

@ -16,10 +16,10 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux.add;
package org.eclipse.jetty.websocket.common.extensions.mux.add;
import org.eclipse.jetty.websocket.core.extensions.mux.op.MuxAddChannelResponse;
import org.eclipse.jetty.websocket.core.io.WebSocketSession;
import org.eclipse.jetty.websocket.common.extensions.mux.op.MuxAddChannelResponse;
import org.eclipse.jetty.websocket.common.io.WebSocketSession;
/**
* Interface for Mux Client to handle receiving a AddChannelResponse

View File

@ -16,16 +16,16 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux.add;
package org.eclipse.jetty.websocket.common.extensions.mux.add;
import java.io.IOException;
import org.eclipse.jetty.websocket.core.api.UpgradeRequest;
import org.eclipse.jetty.websocket.core.api.UpgradeResponse;
import org.eclipse.jetty.websocket.core.extensions.mux.MuxChannel;
import org.eclipse.jetty.websocket.core.extensions.mux.MuxException;
import org.eclipse.jetty.websocket.core.extensions.mux.Muxer;
import org.eclipse.jetty.websocket.core.io.WebSocketSession;
import org.eclipse.jetty.websocket.api.UpgradeRequest;
import org.eclipse.jetty.websocket.api.UpgradeResponse;
import org.eclipse.jetty.websocket.common.extensions.mux.MuxChannel;
import org.eclipse.jetty.websocket.common.extensions.mux.MuxException;
import org.eclipse.jetty.websocket.common.extensions.mux.Muxer;
import org.eclipse.jetty.websocket.common.io.WebSocketSession;
/**
* Server interface, for dealing with incoming AddChannelRequest / AddChannelResponse flows.

View File

@ -16,14 +16,14 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux.op;
package org.eclipse.jetty.websocket.common.extensions.mux.op;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.websocket.core.extensions.mux.MuxControlBlock;
import org.eclipse.jetty.websocket.core.extensions.mux.MuxOp;
import org.eclipse.jetty.websocket.common.extensions.mux.MuxControlBlock;
import org.eclipse.jetty.websocket.common.extensions.mux.MuxOp;
public class MuxAddChannelRequest implements MuxControlBlock
{

View File

@ -16,14 +16,14 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux.op;
package org.eclipse.jetty.websocket.common.extensions.mux.op;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.websocket.core.extensions.mux.MuxControlBlock;
import org.eclipse.jetty.websocket.core.extensions.mux.MuxOp;
import org.eclipse.jetty.websocket.common.extensions.mux.MuxControlBlock;
import org.eclipse.jetty.websocket.common.extensions.mux.MuxOp;
public class MuxAddChannelResponse implements MuxControlBlock
{

View File

@ -16,14 +16,14 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux.op;
package org.eclipse.jetty.websocket.common.extensions.mux.op;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jetty.websocket.core.extensions.mux.MuxControlBlock;
import org.eclipse.jetty.websocket.core.extensions.mux.MuxOp;
import org.eclipse.jetty.websocket.common.extensions.mux.MuxControlBlock;
import org.eclipse.jetty.websocket.common.extensions.mux.MuxOp;
public class MuxDropChannel implements MuxControlBlock
{

View File

@ -16,10 +16,10 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux.op;
package org.eclipse.jetty.websocket.common.extensions.mux.op;
import org.eclipse.jetty.websocket.core.extensions.mux.MuxControlBlock;
import org.eclipse.jetty.websocket.core.extensions.mux.MuxOp;
import org.eclipse.jetty.websocket.common.extensions.mux.MuxControlBlock;
import org.eclipse.jetty.websocket.common.extensions.mux.MuxOp;
public class MuxFlowControl implements MuxControlBlock
{

View File

@ -16,10 +16,10 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.mux.op;
package org.eclipse.jetty.websocket.common.extensions.mux.op;
import org.eclipse.jetty.websocket.core.extensions.mux.MuxControlBlock;
import org.eclipse.jetty.websocket.core.extensions.mux.MuxOp;
import org.eclipse.jetty.websocket.common.extensions.mux.MuxControlBlock;
import org.eclipse.jetty.websocket.common.extensions.mux.MuxOp;
public class MuxNewChannelSlot implements MuxControlBlock
{

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io;
package org.eclipse.jetty.websocket.common.io;
import java.io.IOException;
import java.net.InetSocketAddress;
@ -24,6 +24,7 @@ import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@ -32,23 +33,21 @@ import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FutureCallback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Scheduler;
import org.eclipse.jetty.websocket.core.api.CloseException;
import org.eclipse.jetty.websocket.core.api.StatusCode;
import org.eclipse.jetty.websocket.core.api.SuspendToken;
import org.eclipse.jetty.websocket.core.api.WebSocketConnection;
import org.eclipse.jetty.websocket.core.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.core.protocol.CloseInfo;
import org.eclipse.jetty.websocket.core.protocol.ConnectionState;
import org.eclipse.jetty.websocket.core.protocol.ExtensionConfig;
import org.eclipse.jetty.websocket.core.protocol.Generator;
import org.eclipse.jetty.websocket.core.protocol.OpCode;
import org.eclipse.jetty.websocket.core.protocol.Parser;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.api.CloseException;
import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.api.SuspendToken;
import org.eclipse.jetty.websocket.api.WebSocketConnection;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.api.extensions.Frame;
import org.eclipse.jetty.websocket.common.CloseInfo;
import org.eclipse.jetty.websocket.common.ConnectionState;
import org.eclipse.jetty.websocket.common.Generator;
import org.eclipse.jetty.websocket.common.OpCode;
import org.eclipse.jetty.websocket.common.Parser;
import org.eclipse.jetty.websocket.common.RequestedExtensionConfig;
/**
* Provides the implementation of {@link WebSocketConnection} within the framework of the new {@link Connection} framework of jetty-io
@ -66,7 +65,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
private final FrameQueue queue;
private final AtomicBoolean suspendToken;
private WebSocketSession session;
private List<ExtensionConfig> extensions;
private List<RequestedExtensionConfig> extensions;
private boolean flushing;
private boolean isFilling;
private ConnectionState connectionState;
@ -147,8 +146,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
private void enqueClose(int statusCode, String reason)
{
CloseInfo close = new CloseInfo(statusCode,reason);
FutureCallback<Void> nop = new FutureCallback<>();
output(null,nop,close.asFrame());
output(null,close.asFrame());
}
public void flush()
@ -208,7 +206,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
*
* @return the list of negotiated extensions in use.
*/
public List<ExtensionConfig> getExtensions()
public List<RequestedExtensionConfig> getExtensions()
{
return extensions;
}
@ -365,24 +363,24 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
* Enqueue internal frame from {@link OutgoingFrames} stack for eventual write out on the physical connection.
*/
@Override
public <C> void output(C context, Callback<C> callback, WebSocketFrame frame)
public <C> Future<C> output(C context, Frame frame)
{
if (LOG.isDebugEnabled())
{
LOG.debug("output({}, {}, {})",context,callback,frame);
LOG.debug("output({}, {})",context,frame);
}
synchronized (queue)
{
FrameBytes<C> bytes = null;
if (frame.isControlFrame())
if (frame.getType().isControl())
{
bytes = new ControlFrameBytes<C>(this,callback,context,frame);
bytes = new ControlFrameBytes<C>(this,context,frame);
}
else
{
bytes = new DataFrameBytes<C>(this,callback,context,frame);
bytes = new DataFrameBytes<C>(this,context,frame);
}
scheduleTimeout(bytes);
@ -468,11 +466,12 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
* @param extensions
* the list of negotiated extensions in use.
*/
public void setExtensions(List<ExtensionConfig> extensions)
public void setExtensions(List<RequestedExtensionConfig> extensions)
{
this.extensions = extensions;
}
@Override
public void setSession(WebSocketSession session)
{
this.session = session;

View File

@ -16,16 +16,16 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io;
package org.eclipse.jetty.websocket.common.io;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.protocol.CloseInfo;
import org.eclipse.jetty.websocket.core.protocol.OpCode;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.common.CloseInfo;
import org.eclipse.jetty.websocket.common.OpCode;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
public class ControlFrameBytes<C> extends FrameBytes<C>
{

View File

@ -16,14 +16,14 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io;
package org.eclipse.jetty.websocket.common.io;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
public class DataFrameBytes<C> extends FrameBytes<C>
{

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io;
package org.eclipse.jetty.websocket.common.io;
import java.nio.ByteBuffer;
import java.nio.channels.InterruptedByTimeoutException;
@ -26,7 +26,7 @@ import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Scheduler;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
public abstract class FrameBytes<C> implements Callback<C>, Runnable
{

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io;
package org.eclipse.jetty.websocket.common.io;
import java.util.LinkedList;

View File

@ -16,10 +16,10 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io;
package org.eclipse.jetty.websocket.common.io;
import org.eclipse.jetty.websocket.core.api.WebSocketException;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.api.WebSocketException;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
/**
* Interface for dealing with Incoming Frames.

View File

@ -16,16 +16,16 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io;
package org.eclipse.jetty.websocket.common.io;
import java.util.List;
import org.eclipse.jetty.websocket.core.api.Extension;
import org.eclipse.jetty.websocket.core.api.LogicalConnection;
import org.eclipse.jetty.websocket.common.LogicalConnection;
import org.eclipse.jetty.websocket.common.extensions.AbstractExtension;
public interface InternalConnection extends LogicalConnection
{
void configureFromExtensions(List<Extension> extensions);
void configureFromExtensions(List<AbstractExtension> extensions);
void setIncoming(IncomingFrames incoming);

View File

@ -16,17 +16,17 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io;
package org.eclipse.jetty.websocket.common.io;
import java.io.IOException;
import java.util.concurrent.Future;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.api.extensions.Frame;
/**
* Interface for dealing with outgoing frames.
* Interface for dealing with frames outgoing to the network (eventually)
*/
public interface OutgoingFrames
{
<C> void output(C context, Callback<C> callback, WebSocketFrame frame) throws IOException;
<C> Future<C> output(C context, Frame frame) throws IOException;
}

View File

@ -16,28 +16,30 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io;
package org.eclipse.jetty.websocket.common.io;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.concurrent.Future;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.api.LogicalConnection;
import org.eclipse.jetty.websocket.core.api.SuspendToken;
import org.eclipse.jetty.websocket.core.api.WebSocketConnection;
import org.eclipse.jetty.websocket.core.api.WebSocketException;
import org.eclipse.jetty.websocket.core.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.core.io.event.EventDriver;
import org.eclipse.jetty.websocket.core.protocol.CloseInfo;
import org.eclipse.jetty.websocket.core.protocol.ConnectionState;
import org.eclipse.jetty.websocket.core.protocol.OpCode;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.api.SuspendToken;
import org.eclipse.jetty.websocket.api.WebSocketConnection;
import org.eclipse.jetty.websocket.api.WebSocketException;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.common.CloseInfo;
import org.eclipse.jetty.websocket.common.ConnectionState;
import org.eclipse.jetty.websocket.common.LogicalConnection;
import org.eclipse.jetty.websocket.common.OpCode;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.io.event.EventDriver;
public class WebSocketSession implements WebSocketConnection, IncomingFrames, OutgoingFrames
public class WebSocketSession implements WebSocketConnection, LogicalConnection, IncomingFrames, OutgoingFrames
{
private static final Logger LOG = Log.getLogger(WebSocketSession.class);
@ -84,6 +86,13 @@ public class WebSocketSession implements WebSocketConnection, IncomingFrames, Ou
return websocket;
}
@Override
public InetSocketAddress getLocalAddress()
{
// TODO Auto-generated method stub
return null;
}
public OutgoingFrames getOutgoing()
{
return outgoing;
@ -101,6 +110,13 @@ public class WebSocketSession implements WebSocketConnection, IncomingFrames, Ou
return baseConnection.getRemoteAddress();
}
@Override
public URI getRequestURI()
{
// TODO Auto-generated method stub
return null;
}
@Override
public ConnectionState getState()
{
@ -172,22 +188,21 @@ public class WebSocketSession implements WebSocketConnection, IncomingFrames, Ou
websocket.onConnect();
}
@Override
public <C> void output(C context, Callback<C> callback, WebSocketFrame frame) throws IOException
public <C> Future<C> output(C context, WebSocketFrame frame) throws IOException
{
if (LOG.isDebugEnabled())
{
LOG.debug("output({},{},{}) - {}",context,callback,frame,outgoing);
LOG.debug("output({},{}) - {}",context,frame,outgoing);
}
// forward on to chain
outgoing.output(context,callback,frame);
return outgoing.output(context,frame);
}
/**
* {@inheritDoc}
*/
@Override
public <C> void ping(C context, Callback<C> callback, byte[] payload) throws IOException
public <C> Future<C> ping(C context, byte[] payload) throws IOException
{
// Delegate the application called ping to the OutgoingFrames interface to allow
// extensions to process the frame appropriately.
@ -223,6 +238,20 @@ public class WebSocketSession implements WebSocketConnection, IncomingFrames, Ou
return builder.toString();
}
@Override
public <C> Future<C> write(C context, byte[] buf, int offset, int len) throws IOException
{
// TODO Auto-generated method stub
return null;
}
@Override
public <C> Future<C> write(C context, ByteBuffer buffer) throws IOException
{
// TODO Auto-generated method stub
return null;
}
/**
* {@inheritDoc}
*/
@ -285,4 +314,11 @@ public class WebSocketSession implements WebSocketConnection, IncomingFrames, Ou
frame.setFin(true);
output(context,callback,frame);
}
@Override
public <C> Future<C> write(C context, String message) throws IOException
{
// TODO Auto-generated method stub
return null;
}
}

View File

@ -16,23 +16,23 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io.event;
package org.eclipse.jetty.websocket.common.io.event;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.ByteBuffer;
import org.eclipse.jetty.websocket.core.annotations.WebSocket;
import org.eclipse.jetty.websocket.core.api.WebSocketException;
import org.eclipse.jetty.websocket.core.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.core.io.message.MessageAppender;
import org.eclipse.jetty.websocket.core.io.message.MessageInputStream;
import org.eclipse.jetty.websocket.core.io.message.MessageReader;
import org.eclipse.jetty.websocket.core.io.message.SimpleBinaryMessage;
import org.eclipse.jetty.websocket.core.io.message.SimpleTextMessage;
import org.eclipse.jetty.websocket.core.protocol.CloseInfo;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.api.WebSocketException;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.api.extensions.Frame;
import org.eclipse.jetty.websocket.common.CloseInfo;
import org.eclipse.jetty.websocket.common.io.message.MessageAppender;
import org.eclipse.jetty.websocket.common.io.message.MessageInputStream;
import org.eclipse.jetty.websocket.common.io.message.MessageReader;
import org.eclipse.jetty.websocket.common.io.message.SimpleBinaryMessage;
import org.eclipse.jetty.websocket.common.io.message.SimpleTextMessage;
/**
* Handler for Annotated User WebSocket objects.
@ -134,7 +134,7 @@ public class AnnotatedEventDriver extends EventDriver
}
@Override
public void onFrame(WebSocketFrame frame)
public void onFrame(Frame frame)
{
if (events.onFrame != null)
{

View File

@ -16,31 +16,31 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io.event;
package org.eclipse.jetty.websocket.common.io.event;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.FutureCallback;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.api.CloseException;
import org.eclipse.jetty.websocket.core.api.StatusCode;
import org.eclipse.jetty.websocket.core.api.WebSocketException;
import org.eclipse.jetty.websocket.core.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.core.io.IncomingFrames;
import org.eclipse.jetty.websocket.core.io.WebSocketSession;
import org.eclipse.jetty.websocket.core.protocol.CloseInfo;
import org.eclipse.jetty.websocket.core.protocol.OpCode;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.api.CloseException;
import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.api.WebSocketException;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.api.extensions.Frame;
import org.eclipse.jetty.websocket.api.extensions.FrameHandler;
import org.eclipse.jetty.websocket.common.CloseInfo;
import org.eclipse.jetty.websocket.common.OpCode;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.io.WebSocketSession;
/**
* EventDriver is the main interface between the User's WebSocket POJO and the internal jetty implementation of WebSocket.
*/
public abstract class EventDriver implements IncomingFrames
public abstract class EventDriver implements FrameHandler
{
protected final Logger LOG;
protected final WebSocketPolicy policy;
@ -65,24 +65,7 @@ public abstract class EventDriver implements IncomingFrames
}
@Override
public final void incoming(WebSocketException e)
{
if (LOG.isDebugEnabled())
{
LOG.debug("incoming(WebSocketException)",e);
}
if (e instanceof CloseException)
{
CloseException close = (CloseException)e;
terminateConnection(close.getStatusCode(),close.getMessage());
}
onException(e);
}
@Override
public final void incoming(WebSocketFrame frame)
public void handleFrame(Frame frame)
{
if (LOG.isDebugEnabled())
{
@ -127,7 +110,7 @@ public abstract class EventDriver implements IncomingFrames
LOG.debug("Pong with {}",BufferUtil.toDetailString(pongBuf));
}
}
session.output("pong",new FutureCallback<String>(),pong);
session.output("pong",pong);
break;
}
case OpCode.BINARY:
@ -156,6 +139,23 @@ public abstract class EventDriver implements IncomingFrames
}
}
// FIXME: need flow of exceptions ...
public final void incoming(WebSocketException e)
{
if (LOG.isDebugEnabled())
{
LOG.debug("incoming(WebSocketException)",e);
}
if (e instanceof CloseException)
{
CloseException close = (CloseException)e;
terminateConnection(close.getStatusCode(),close.getMessage());
}
onException(e);
}
public abstract void onBinaryFrame(ByteBuffer buffer, boolean fin) throws IOException;
public abstract void onBinaryMessage(byte[] data);
@ -166,7 +166,7 @@ public abstract class EventDriver implements IncomingFrames
public abstract void onException(WebSocketException e);
public abstract void onFrame(WebSocketFrame frame);
public abstract void onFrame(Frame frame);
public abstract void onTextFrame(ByteBuffer buffer, boolean fin) throws IOException;

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io.event;
package org.eclipse.jetty.websocket.common.io.event;
import java.io.InputStream;
import java.io.Reader;
@ -26,16 +26,16 @@ import java.lang.reflect.Modifier;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.websocket.core.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.core.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.core.annotations.OnWebSocketFrame;
import org.eclipse.jetty.websocket.core.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.core.annotations.WebSocket;
import org.eclipse.jetty.websocket.core.api.InvalidWebSocketException;
import org.eclipse.jetty.websocket.core.api.WebSocketConnection;
import org.eclipse.jetty.websocket.core.api.WebSocketListener;
import org.eclipse.jetty.websocket.core.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.core.protocol.Frame;
import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
import org.eclipse.jetty.websocket.api.WebSocketConnection;
import org.eclipse.jetty.websocket.api.WebSocketListener;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketFrame;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.api.extensions.Frame;
/**
* Create EventDriver implementations.

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io.event;
package org.eclipse.jetty.websocket.common.io.event;
import java.io.InputStream;
import java.io.Reader;
@ -25,8 +25,8 @@ import java.lang.reflect.Method;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.api.WebSocketConnection;
import org.eclipse.jetty.websocket.core.api.WebSocketException;
import org.eclipse.jetty.websocket.api.WebSocketConnection;
import org.eclipse.jetty.websocket.api.WebSocketException;
public class EventMethod
{

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io.event;
package org.eclipse.jetty.websocket.common.io.event;
/**
* A representation of the methods available to call for a particular class.

View File

@ -16,13 +16,13 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io.event;
package org.eclipse.jetty.websocket.common.io.event;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.websocket.core.api.InvalidWebSocketException;
import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
@SuppressWarnings("serial")
public class InvalidSignatureException extends InvalidWebSocketException

View File

@ -16,19 +16,19 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io.event;
package org.eclipse.jetty.websocket.common.io.event;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.eclipse.jetty.websocket.core.api.WebSocketException;
import org.eclipse.jetty.websocket.core.api.WebSocketListener;
import org.eclipse.jetty.websocket.core.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.core.io.message.MessageAppender;
import org.eclipse.jetty.websocket.core.io.message.SimpleBinaryMessage;
import org.eclipse.jetty.websocket.core.io.message.SimpleTextMessage;
import org.eclipse.jetty.websocket.core.protocol.CloseInfo;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.api.WebSocketException;
import org.eclipse.jetty.websocket.api.WebSocketListener;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.api.extensions.Frame;
import org.eclipse.jetty.websocket.common.CloseInfo;
import org.eclipse.jetty.websocket.common.io.message.MessageAppender;
import org.eclipse.jetty.websocket.common.io.message.SimpleBinaryMessage;
import org.eclipse.jetty.websocket.common.io.message.SimpleTextMessage;
/**
* Handler for {@link WebSocketListener} based User WebSocket implementations.
@ -89,7 +89,7 @@ public class ListenerEventDriver extends EventDriver
}
@Override
public void onFrame(WebSocketFrame frame)
public void onFrame(Frame frame)
{
/* ignore, not supported by WebSocketListener */
}

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io.event;
package org.eclipse.jetty.websocket.common.io.event;
import java.util.ArrayList;

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io.message;
package org.eclipse.jetty.websocket.common.io.message;
import java.io.IOException;
import java.nio.ByteBuffer;

View File

@ -16,14 +16,14 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io.message;
package org.eclipse.jetty.websocket.common.io.message;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.websocket.core.io.event.AnnotatedEventDriver;
import org.eclipse.jetty.websocket.common.io.event.AnnotatedEventDriver;
/**
* Support class for reading binary message data as an InputStream.

View File

@ -16,14 +16,14 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io.message;
package org.eclipse.jetty.websocket.common.io.message;
import java.io.IOException;
import java.io.Reader;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.Utf8StringBuilder;
import org.eclipse.jetty.websocket.core.io.event.AnnotatedEventDriver;
import org.eclipse.jetty.websocket.common.io.event.AnnotatedEventDriver;
/**
* Support class for reading text message data as an Reader.

View File

@ -16,14 +16,14 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io.message;
package org.eclipse.jetty.websocket.common.io.message;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.websocket.core.io.event.EventDriver;
import org.eclipse.jetty.websocket.common.io.event.EventDriver;
public class SimpleBinaryMessage implements MessageAppender
{

View File

@ -16,13 +16,13 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io.message;
package org.eclipse.jetty.websocket.common.io.message;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.Utf8StringBuilder;
import org.eclipse.jetty.websocket.core.io.event.EventDriver;
import org.eclipse.jetty.websocket.common.io.event.EventDriver;
public class SimpleTextMessage implements MessageAppender
{

View File

@ -16,11 +16,11 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io.payload;
package org.eclipse.jetty.websocket.common.io.payload;
import java.nio.ByteBuffer;
import org.eclipse.jetty.websocket.core.protocol.OpCode;
import org.eclipse.jetty.websocket.common.OpCode;
/**
* Validate UTF8 correctness for {@link OpCode#CLOSE} Reason message.

View File

@ -16,11 +16,11 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io.payload;
package org.eclipse.jetty.websocket.common.io.payload;
import java.nio.ByteBuffer;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
public class DeMaskProcessor implements PayloadProcessor
{

View File

@ -16,11 +16,11 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io.payload;
package org.eclipse.jetty.websocket.common.io.payload;
import java.nio.ByteBuffer;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
/**
* payload validator does no validation.

View File

@ -16,12 +16,12 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io.payload;
package org.eclipse.jetty.websocket.common.io.payload;
import java.nio.ByteBuffer;
import org.eclipse.jetty.websocket.core.api.BadPayloadException;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.api.BadPayloadException;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
/**
* Process the payload (for demasking, validating, etc..)

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io.payload;
package org.eclipse.jetty.websocket.common.io.payload;
import java.io.IOException;
import java.nio.ByteBuffer;
@ -25,8 +25,8 @@ import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Utf8Appendable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.api.BadPayloadException;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.api.BadPayloadException;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
/**
* Used to perform validation of UTF8 payload contents (for fast-fail reasons)

View File

@ -1,46 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.eclipse.jetty.websocket.core.api.WebSocketConnection;
/**
* Annotation for tagging methods to receive connection close events.
* <p>
* Acceptable method patterns.<br>
* Note: <code>methodName</code> can be any name you want to use.
* <ol>
* <li><code>public void methodName(int statusCode, String reason)</code></li>
* <li><code>public void methodName({@link WebSocketConnection} conn, int statusCode, String reason)</code></li>
* </ol>
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value =
{ ElementType.METHOD })
public @interface OnWebSocketClose
{
/* no config */
}

View File

@ -1,45 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.eclipse.jetty.websocket.core.api.WebSocketConnection;
/**
* Annotation for tagging methods to receive connection open events.
* <p>
* Only 1 acceptable method pattern for this annotation.<br>
* Note: <code>methodName</code> can be any name you want to use.
* <ol>
* <li><code>public void methodName({@link WebSocketConnection} conn)</code></li>
* </ol>
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value =
{ ElementType.METHOD })
public @interface OnWebSocketConnect
{
/* no config */
}

View File

@ -1,49 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.eclipse.jetty.websocket.core.api.WebSocketConnection;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
/**
* (ADVANCED) Annotation for tagging methods to receive frame events.
* <p>
* Note: any frame derived from {@link WebSocketFrame} is acceptable to use as the last parameter here.
* <p>
* Acceptable method patterns.<br>
* Note: <code>methodName</code> can be any name you want to use.
* <ol>
* <li><code>public void methodName({@link WebSocketFrame} frame)</code></li>
* <li><code>public void methodName({@link WebSocketConnection} conn, {@link WebSocketFrame} frame)</code></li>
* </ol>
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value =
{ ElementType.METHOD })
public @interface OnWebSocketFrame
{
/* no config */
}

View File

@ -1,61 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.annotations;
import java.io.Reader;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.eclipse.jetty.websocket.core.api.WebSocketConnection;
/**
* Annotation for tagging methods to receive Binary or Text Message events.
* <p>
* Acceptable method patterns.<br>
* Note: <code>methodName</code> can be any name you want to use.
* <p>
* <u>Text Message Versions</u>
* <ol>
* <li><code>public void methodName(String text)</code></li>
* <li><code>public void methodName({@link WebSocketConnection} conn, String text)</code></li>
* <li><code>public void methodName(Reader reader)</code></li>
* <li><code>public void methodName({@link WebSocketConnection} conn, Reader reader)</code></li>
* </ol>
* Note: that the {@link Reader} in this case will always use UTF-8 encoding/charset (this is dictated by the RFC 6455 spec for Text Messages. If you need to
* use a non-UTF-8 encoding/charset, you are instructed to use the binary messaging techniques.
* <p>
* <u>Binary Message Versions</u>
* <ol>
* <li><code>public void methodName(byte buf[], int offset, int length)</code></li>
* <li><code>public void methodName({@link WebSocketConnection} conn, byte buf[], int offset, int length)</code></li>
* <li><code>public void methodName(InputStream stream)</code></li>
* <li><code>public void methodName({@link WebSocketConnection} conn, InputStream stream)</code></li>
* </ol>
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value =
{ ElementType.METHOD })
public @interface OnWebSocketMessage
{
/* no config */
}

View File

@ -1,43 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Tags a POJO as being a WebSocket class.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value =
{ ElementType.TYPE })
public @interface WebSocket
{
int maxBinarySize() default -2;
int maxBufferSize() default -2;
int maxIdleTime() default -2;
int maxTextSize() default -2;
}

View File

@ -1,46 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
import org.eclipse.jetty.websocket.core.extensions.compress.PerMessageCompressionExtension;
/**
* Exception to terminate the connection because it has received data within a frame payload that was not consistent with the requirements of that frame
* payload. (eg: not UTF-8 in a text frame, or a bad data seen in the {@link PerMessageCompressionExtension})
*
* @see StatusCode#BAD_PAYLOAD
*/
@SuppressWarnings("serial")
public class BadPayloadException extends CloseException
{
public BadPayloadException(String message)
{
super(StatusCode.BAD_PAYLOAD,message);
}
public BadPayloadException(String message, Throwable t)
{
super(StatusCode.BAD_PAYLOAD,message,t);
}
public BadPayloadException(Throwable t)
{
super(StatusCode.BAD_PAYLOAD,t);
}
}

View File

@ -1,49 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
@SuppressWarnings("serial")
public class CloseException extends WebSocketException
{
private int statusCode;
public CloseException(int closeCode, String message)
{
super(message);
this.statusCode = closeCode;
}
public CloseException(int closeCode, String message, Throwable cause)
{
super(message,cause);
this.statusCode = closeCode;
}
public CloseException(int closeCode, Throwable cause)
{
super(cause);
this.statusCode = closeCode;
}
public int getStatusCode()
{
return statusCode;
}
}

View File

@ -1,45 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
import org.eclipse.jetty.websocket.core.annotations.WebSocket;
/**
* Indicating that the provided Class is not a valid WebSocket as defined by the API.
* <p>
* A valid WebSocket should do one of the following:
* <ul>
* <li>Implement {@link WebSocketListener}</li>
* <li>Extend {@link WebSocketAdapter}</li>
* <li>Declare the {@link WebSocket &#064;WebSocket} annotation on the type</li>
* </ul>
*/
@SuppressWarnings("serial")
public class InvalidWebSocketException extends WebSocketException
{
public InvalidWebSocketException(String message)
{
super(message);
}
public InvalidWebSocketException(String message, Throwable cause)
{
super(message,cause);
}
}

View File

@ -1,43 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
/**
* Exception when a message is too large for the internal buffers occurs and should trigger a connection close.
*
* @see StatusCode#MESSAGE_TOO_LARGE
*/
@SuppressWarnings("serial")
public class MessageTooLargeException extends CloseException
{
public MessageTooLargeException(String message)
{
super(StatusCode.MESSAGE_TOO_LARGE,message);
}
public MessageTooLargeException(String message, Throwable t)
{
super(StatusCode.MESSAGE_TOO_LARGE,message,t);
}
public MessageTooLargeException(Throwable t)
{
super(StatusCode.MESSAGE_TOO_LARGE,t);
}
}

View File

@ -1,43 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
/**
* Exception when a violation of policy occurs and should trigger a connection close.
*
* @see StatusCode#POLICY_VIOLATION
*/
@SuppressWarnings("serial")
public class PolicyViolationException extends CloseException
{
public PolicyViolationException(String message)
{
super(StatusCode.POLICY_VIOLATION,message);
}
public PolicyViolationException(String message, Throwable t)
{
super(StatusCode.POLICY_VIOLATION,message,t);
}
public PolicyViolationException(Throwable t)
{
super(StatusCode.POLICY_VIOLATION,t);
}
}

View File

@ -1,41 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
/**
* Per spec, a protocol error should result in a Close frame of status code 1002 (PROTOCOL_ERROR)
*/
@SuppressWarnings("serial")
public class ProtocolException extends CloseException
{
public ProtocolException(String message)
{
super(StatusCode.PROTOCOL,message);
}
public ProtocolException(String message, Throwable t)
{
super(StatusCode.PROTOCOL,message,t);
}
public ProtocolException(Throwable t)
{
super(StatusCode.PROTOCOL,t);
}
}

View File

@ -1,141 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
/**
* The <a href="https://tools.ietf.org/html/rfc6455#section-7.4">RFC 6455 specified status codes</a> and <a
* href="https://www.iana.org/assignments/websocket/websocket.xml#close-code-number-rules">IANA: WebSocket Close Code Number Registry</a>
*/
public class StatusCode
{
/**
* 1000 indicates a normal closure, meaning that the purpose for which the connection was established has been fulfilled.
* <p>
* See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
*/
public final static int NORMAL = 1000;
/**
* 1001 indicates that an endpoint is "going away", such as a server going down or a browser having navigated away from a page.
* <p>
* See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
*/
public final static int SHUTDOWN = 1001;
/**
* 1002 indicates that an endpoint is terminating the connection due to a protocol error.
* <p>
* See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
*/
public final static int PROTOCOL = 1002;
/**
* 1003 indicates that an endpoint is terminating the connection because it has received a type of data it cannot accept (e.g., an endpoint that understands
* only text data MAY send this if it receives a binary message).
* <p>
* See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
*/
public final static int BAD_DATA = 1003;
/**
* Reserved. The specific meaning might be defined in the future.
* <p>
* See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
*/
public final static int UNDEFINED = 1004;
/**
* 1005 is a reserved value and MUST NOT be set as a status code in a Close control frame by an endpoint. It is designated for use in applications expecting
* a status code to indicate that no status code was actually present.
* <p>
* See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
*/
public final static int NO_CODE = 1005;
/**
* 1006 is a reserved value and MUST NOT be set as a status code in a Close control frame by an endpoint. It is designated for use in applications expecting
* a status code to indicate that the connection was closed abnormally, e.g., without sending or receiving a Close control frame.
* <p>
* See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
*/
public final static int NO_CLOSE = 1006;
/**
* 1007 indicates that an endpoint is terminating the connection because it has received data within a message that was not consistent with the type of the
* message (e.g., non-UTF-8 [<a href="https://tools.ietf.org/html/rfc3629">RFC3629</a>] data within a text message).
* <p>
* See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
*/
public final static int BAD_PAYLOAD = 1007;
/**
* 1008 indicates that an endpoint is terminating the connection because it has received a message that violates its policy. This is a generic status code
* that can be returned when there is no other more suitable status code (e.g., 1003 or 1009) or if there is a need to hide specific details about the
* policy.
* <p>
* See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
*/
public final static int POLICY_VIOLATION = 1008;
/**
* 1009 indicates that an endpoint is terminating the connection because it has received a message that is too big for it to process.
* <p>
* See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
*/
public final static int MESSAGE_TOO_LARGE = 1009;
/**
* 1010 indicates that an endpoint (client) is terminating the connection because it has expected the server to negotiate one or more extension, but the
* server didn't return them in the response message of the WebSocket handshake. The list of extensions that are needed SHOULD appear in the /reason/ part
* of the Close frame. Note that this status code is not used by the server, because it can fail the WebSocket handshake instead.
* <p>
* See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
*/
public final static int REQUIRED_EXTENSION = 1010;
/**
* 1011 indicates that a server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request.
* <p>
* See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
*/
public final static int SERVER_ERROR = 1011;
/**
* 1012 indicates that the service is restarted. a client may reconnect, and if it chooses to do, should reconnect using a randomized delay of 5 - 30s.
* <p>
* See <a href="https://www.ietf.org/mail-archive/web/hybi/current/msg09649.html">[hybi] Additional WebSocket Close Error Codes</a>
*/
public final static int SERVICE_RESTART = 1012;
/**
* 1013 indicates that the service is experiencing overload. a client should only connect to a different IP (when there are multiple for the target) or
* reconnect to the same IP upon user action.
* <p>
* See <a href="https://www.ietf.org/mail-archive/web/hybi/current/msg09649.html">[hybi] Additional WebSocket Close Error Codes</a>
*/
public final static int TRY_AGAIN_LATER = 1013;
/**
* 1015 is a reserved value and MUST NOT be set as a status code in a Close control frame by an endpoint. It is designated for use in applications expecting
* a status code to indicate that the connection was closed due to a failure to perform a TLS handshake (e.g., the server certificate can't be verified).
* <p>
* See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
*/
public final static int FAILED_TLS_HANDSHAKE = 1015;
}

View File

@ -1,30 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
/**
* Connection suspend token
*/
public interface SuspendToken
{
/**
* Resume a previously suspended connection.
*/
void resume();
}

View File

@ -1,46 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
/**
* Exception during WebSocket Upgrade Handshake.
*/
@SuppressWarnings("serial")
public class UpgradeException extends WebSocketException
{
public UpgradeException()
{
super();
}
public UpgradeException(String message)
{
super(message);
}
public UpgradeException(String message, Throwable cause)
{
super(message,cause);
}
public UpgradeException(Throwable cause)
{
super(cause);
}
}

View File

@ -1,59 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
import java.util.List;
import java.util.Map;
import org.eclipse.jetty.websocket.core.protocol.ExtensionConfig;
public interface UpgradeRequest
{
public void addExtensions(String... extConfigs);
public Map<String, String> getCookieMap();
public List<ExtensionConfig> getExtensions();
public String getHeader(String name);
public Map<String, List<String>> getHeaders();
public String getHost();
public String getHttpVersion();
public String getMethod();
public String getOrigin();
public Map<String,String[]> getParameterMap();
public String getQueryString();
public String getRemoteURI();
public List<String> getSubProtocols();
public boolean hasSubProtocol(String test);
public boolean isOrigin(String test);
public void setSubProtocols(String protocols);
}

View File

@ -1,99 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.jetty.websocket.core.protocol.ExtensionConfig;
public interface UpgradeResponse
{
public void addHeader(String name, String value);
/**
* Get the accepted WebSocket protocol.
*
* @return the accepted WebSocket protocol.
*/
public String getAcceptedSubProtocol();
/**
* Get the list of extensions that should be used for the websocket.
*
* @return the list of negotiated extensions to use.
*/
public List<ExtensionConfig> getExtensions();
public Set<String> getHeaderNamesSet();
public String getHeaderValue(String name);
public Iterator<String> getHeaderValues(String name);
public int getStatusCode();
public String getStatusReason();
public boolean isSuccess();
/**
* Issue a forbidden upgrade response.
* <p>
* This means that the websocket endpoint was valid, but the conditions to use a WebSocket resulted in a forbidden access.
* <p>
* Use this when the origin or authentication is invalid.
*
* @param message
* the short 1 line detail message about the forbidden response
* @throws IOException
*/
public void sendForbidden(String message) throws IOException;
/**
* Set the accepted WebSocket Protocol.
*
* @param protocol
* the protocol to list as accepted
*/
public void setAcceptedSubProtocol(String protocol);
/**
* Set the list of extensions that are approved for use with this websocket.
* <p>
* This is Advanced usage of the {@link WebSocketCreator} to allow for a custom set of negotiated extensions.
* <p>
* Notes:
* <ul>
* <li>Per the spec you cannot add extensions that have not been seen in the {@link UpgradeRequest}, just remove entries you don't want to use</li>
* <li>If this is unused, or a null is passed, then the list negotiation will follow default behavior and use the complete list of extensions that are
* available in this WebSocket server implementation.</li>
* </ul>
*
* @param extensions
* the list of extensions to use.
*/
public void setExtensions(List<ExtensionConfig> extensions);
public void setHeader(String name, String value);
public void validateWebSocketHash(String expectedHash) throws UpgradeException;
}

View File

@ -1,83 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
import org.eclipse.jetty.websocket.core.api.io.WebSocketBlockingConnection;
/**
* Default implementation of the {@link WebSocketListener}.
* <p>
* Convenient abstract class to base standard WebSocket implementations off of.
*/
public class WebSocketAdapter implements WebSocketListener
{
private WebSocketConnection connection;
private WebSocketBlockingConnection blocking;
public WebSocketBlockingConnection getBlockingConnection()
{
return blocking;
}
public WebSocketConnection getConnection()
{
return connection;
}
public boolean isConnected()
{
return (connection != null) && (connection.isOpen());
}
public boolean isNotConnected()
{
return (connection == null) || (!connection.isOpen());
}
@Override
public void onWebSocketBinary(byte[] payload, int offset, int len)
{
/* do nothing */
}
@Override
public void onWebSocketClose(int statusCode, String reason)
{
this.connection = null;
}
@Override
public void onWebSocketConnect(WebSocketConnection connection)
{
this.connection = connection;
this.blocking = new WebSocketBlockingConnection(this.connection);
}
@Override
public void onWebSocketException(WebSocketException error)
{
/* do nothing */
}
@Override
public void onWebSocketText(String message)
{
/* do nothing */
}
}

View File

@ -1,31 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
/**
* Behavior for how the WebSocket should operate.
* <p>
* This dictated by the <a href="https://tools.ietf.org/html/rfc6455">RFC 6455</a> spec in various places, where certain behavior must be performed depending on
* operation as a <a href="https://tools.ietf.org/html/rfc6455#section-4.1">CLIENT</a> vs a <a href="https://tools.ietf.org/html/rfc6455#section-4.2">SERVER</a>
*/
public enum WebSocketBehavior
{
CLIENT,
SERVER;
}

View File

@ -1,75 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.Callback;
/**
* Connection interface for WebSocket protocol <a href="https://tools.ietf.org/html/rfc6455">RFC-6455</a>.
*/
public interface WebSocketConnection extends LogicalConnection
{
/**
* Access the (now read-only) {@link WebSocketPolicy} in use for this connection.
*
* @return the policy in use
*/
WebSocketPolicy getPolicy();
/**
* Get the SubProtocol in use for this connection.
*
* @return the negotiated sub protocol name in use for this connection, can be null if there is no sub-protocol negotiated.
*/
String getSubProtocol();
/**
* Send a single ping messages.
* <p>
* NIO style with callbacks, allows for knowledge of successful ping send.
* <p>
* Use @OnWebSocketFrame and monitor Pong frames
*/
<C> void ping(C context, Callback<C> callback, byte payload[]) throws IOException;
/**
* Send a a binary message.
* <p>
* NIO style with callbacks, allows for concurrent results of the write operation.
*/
<C> void write(C context, Callback<C> callback, byte buf[], int offset, int len) throws IOException;
/**
* Send a a binary message.
* <p>
* NIO style with callbacks, allows for concurrent results of the write operation.
*/
<C> void write(C context, Callback<C> callback, ByteBuffer buffer) throws IOException;
/**
* Send a series of text messages.
* <p>
* NIO style with callbacks, allows for concurrent results of the entire write operation. (Callback is only called once at the end of processing all of the
* messages)
*/
<C> void write(C context, Callback<C> callback, String message) throws IOException;
}

View File

@ -1,46 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
/**
* A recoverable exception within the websocket framework.
*/
@SuppressWarnings("serial")
public class WebSocketException extends RuntimeException
{
public WebSocketException()
{
super();
}
public WebSocketException(String message)
{
super(message);
}
public WebSocketException(String message, Throwable cause)
{
super(message,cause);
}
public WebSocketException(Throwable cause)
{
super(cause);
}
}

View File

@ -1,78 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
/**
* Basic WebSocket Listener interface for incoming WebSocket events.
*/
public interface WebSocketListener
{
/**
* A WebSocket binary frame has been received.
*
* @param payload the raw payload array received
* @param offset the offset in the payload array where the data starts
* @param len the length of bytes in the payload
*/
void onWebSocketBinary(byte payload[], int offset, int len);
/**
* A Close Event was received.
* <p>
* The underlying {@link WebSocketConnection} will be considered closed at this point.
*
* @param statusCode
* the close status code. (See {@link StatusCode})
* @param reason
* the optional reason for the close.
*/
void onWebSocketClose(int statusCode, String reason);
/**
* A WebSocketConnection has connected successfully and is ready to be used.
* <p>
* Note: It is a good idea to track this connection as a field in your object so that you can write messages back.
*
* @param connection
* the connection to use to send messages on.
*/
void onWebSocketConnect(WebSocketConnection connection);
/**
* A WebSocket exception has occurred.
* <p>
* Usually this occurs from bad / malformed incoming packets. (example: bad UTF8 data, frames that are too big, violations of the spec)
* <p>
* This will result in the {@link WebSocketConnection} being closed by the implementing side.
* <p>
* Note: you will receive no {@link #onWebSocketClose(int, String)} as this condition results in the API calling
* {@link WebSocketConnection#close(int, String)} for you.
*
* @param error
* the error that occurred.
*/
void onWebSocketException(WebSocketException error);
/**
* A WebSocket Text frame was received.
*
* @param message
*/
void onWebSocketText(String message);
}

View File

@ -1,208 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api;
/**
* Settings for WebSocket operations.
*/
public class WebSocketPolicy
{
public static WebSocketPolicy newClientPolicy()
{
return new WebSocketPolicy(WebSocketBehavior.CLIENT);
}
public static WebSocketPolicy newServerPolicy()
{
return new WebSocketPolicy(WebSocketBehavior.SERVER);
}
/**
* Automatically fragment large frames.
* <p>
* If frames are encountered at size larger than {@link #maxPayloadSize} then they are automatically fragmented into pieces fitting within the
* maxPayloadSize.
* <p>
* Default: false
*/
private boolean autoFragment = false;
/**
* The maximum allowed payload size (validated in both directions)
* <p>
* Default: 65536 (64K)
*/
private int maxPayloadSize = 65536;
/**
* The maximum size of a text message during parsing/generating.
* <p>
* Default: 16384 (16 K)
*/
private int maxTextMessageSize = 16384;
/**
* The maximum size of a binary message during parsing/generating.
* <p>
* Default: -1 (no validation)
*/
private int maxBinaryMessageSize = -1;
/**
* Maximum Message Buffer size, which is also the max frame byte size.
* <p>
* Default: 65536 (64 K)
*/
private int bufferSize = 65536;
// TODO: change bufferSize to windowSize for FrameBytes logic?
/**
* The time in ms (milliseconds) that a websocket may be idle before closing.
* <p>
* Default: 300000 (ms)
*/
private int idleTimeout = 300000;
/**
* Behavior of the websockets
*/
private final WebSocketBehavior behavior;
public WebSocketPolicy(WebSocketBehavior behavior)
{
this.behavior = behavior;
}
public void assertValidBinaryMessageSize(int requestedSize)
{
if (maxBinaryMessageSize > 0)
{
// validate it
if (requestedSize > maxBinaryMessageSize)
{
throw new MessageTooLargeException("Requested binary message size [" + requestedSize + "] exceeds maximum size [" + maxBinaryMessageSize + "]");
}
}
}
public void assertValidPayloadLength(int payloadLength)
{
// validate to buffer sizes
if (payloadLength > maxPayloadSize)
{
throw new MessageTooLargeException("Requested payload length [" + payloadLength + "] exceeds maximum size [" + maxPayloadSize + "]");
}
}
public void assertValidTextMessageSize(int requestedSize)
{
if (maxTextMessageSize > 0)
{
// validate it
if (requestedSize > maxTextMessageSize)
{
throw new MessageTooLargeException("Requested text message size [" + requestedSize + "] exceeds maximum size [" + maxTextMessageSize + "]");
}
}
}
public WebSocketPolicy clonePolicy()
{
WebSocketPolicy clone = new WebSocketPolicy(this.behavior);
clone.autoFragment = this.autoFragment;
clone.idleTimeout = this.idleTimeout;
clone.bufferSize = this.bufferSize;
clone.maxPayloadSize = this.maxPayloadSize;
clone.maxBinaryMessageSize = this.maxBinaryMessageSize;
clone.maxTextMessageSize = this.maxTextMessageSize;
return clone;
}
public WebSocketBehavior getBehavior()
{
return behavior;
}
public int getBufferSize()
{
return bufferSize;
}
public int getIdleTimeout()
{
return idleTimeout;
}
public int getMaxBinaryMessageSize()
{
return maxBinaryMessageSize;
}
public int getMaxPayloadSize()
{
return maxPayloadSize;
}
public int getMaxTextMessageSize()
{
return maxTextMessageSize;
}
public boolean isAutoFragment()
{
return autoFragment;
}
public void setAutoFragment(boolean autoFragment)
{
this.autoFragment = autoFragment;
}
public void setBufferSize(int bufferSize)
{
this.bufferSize = bufferSize;
}
public void setIdleTimeout(int idleTimeout)
{
this.idleTimeout = idleTimeout;
}
public void setMaxBinaryMessageSize(int maxBinaryMessageSize)
{
this.maxBinaryMessageSize = maxBinaryMessageSize;
}
public void setMaxPayloadSize(int maxPayloadSize)
{
if (maxPayloadSize < bufferSize)
{
throw new IllegalStateException("Cannot have payload size be smaller than buffer size");
}
this.maxPayloadSize = maxPayloadSize;
}
public void setMaxTextMessageSize(int maxTextMessageSize)
{
this.maxTextMessageSize = maxTextMessageSize;
}
}

View File

@ -1,122 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api.io;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import org.eclipse.jetty.util.FutureCallback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.api.WebSocketConnection;
import org.eclipse.jetty.websocket.core.io.WebSocketSession;
/**
* For working with the {@link WebSocketConnection} in a blocking technique.
* <p>
* This is an end-user accessible class.
*/
public class WebSocketBlockingConnection
{
private static class Blocker extends FutureCallback<String>
{
@Override
public void completed(String context)
{
LOG.debug("completed({})",context);
super.completed(context);
}
@Override
public void failed(String context, Throwable cause)
{
LOG.debug("failed({},{})",context,cause);
super.failed(context,cause);
}
@Override
public String toString()
{
return String.format("%s[%s]",Blocker.class.getSimpleName(),super.toString());
}
}
private static final Logger LOG = Log.getLogger(WebSocketBlockingConnection.class);
private static final String CONTEXT_BINARY = "BLOCKING_BINARY";
private static final String CONTEXT_TEXT = "BLOCKING_TEXT";
private final WebSocketSession conn;
public WebSocketBlockingConnection(WebSocketConnection conn)
{
if (conn instanceof WebSocketSession)
{
this.conn = (WebSocketSession)conn;
}
else
{
throw new IllegalArgumentException("WebSocketConnection must implement internal WebSocketSession interface");
}
}
/**
* Send a binary message.
* <p>
* Basic usage, results in a blocking write.
*/
public void write(byte[] data, int offset, int length) throws IOException
{
try
{
Blocker blocker = new Blocker();
conn.write(CONTEXT_BINARY,blocker,data,offset,length);
blocker.get(); // block till finished
}
catch (InterruptedException e)
{
throw new IOException("Blocking write failed",e);
}
catch (ExecutionException e)
{
FutureCallback.rethrow(e);
}
}
/**
* Send text message.
* <p>
* Basic usage, results in a blocking write.
*/
public void write(String message) throws IOException
{
try
{
Blocker blocker = new Blocker();
conn.write(CONTEXT_TEXT,blocker,message);
blocker.get(); // block till finished
}
catch (InterruptedException e)
{
throw new IOException("Blocking write failed",e);
}
catch (ExecutionException e)
{
FutureCallback.rethrow(e);
}
}
}

View File

@ -1,50 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api.io;
import java.io.IOException;
import java.io.OutputStream;
import org.eclipse.jetty.websocket.core.api.WebSocketConnection;
import org.eclipse.jetty.websocket.core.io.WebSocketSession;
public class WebSocketOutputStream extends OutputStream
{
private final WebSocketSession conn;
public WebSocketOutputStream(WebSocketConnection conn)
{
if (conn instanceof WebSocketSession)
{
this.conn = (WebSocketSession)conn;
}
else
{
throw new IllegalArgumentException("WebSocketConnection must implement internal WebSocketSession interface");
}
}
@Override
public void write(int b) throws IOException
{
// TODO Auto-generated method stub
}
}

View File

@ -1,66 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.api.io;
import java.io.IOException;
import java.io.Writer;
import java.nio.charset.Charset;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.websocket.core.api.WebSocketConnection;
import org.eclipse.jetty.websocket.core.io.WebSocketSession;
public class WebSocketWriter extends Writer
{
private final Charset charset = StringUtil.__UTF8_CHARSET;
private final WebSocketSession conn;
public WebSocketWriter(WebSocketConnection conn)
{
if (conn instanceof WebSocketSession)
{
this.conn = (WebSocketSession)conn;
}
else
{
throw new IllegalArgumentException("WebSocketConnection must implement internal WebSocketSession interface");
}
}
@Override
public void close() throws IOException
{
// TODO Auto-generated method stub
}
@Override
public void flush() throws IOException
{
// TODO Auto-generated method stub
}
@Override
public void write(char[] cbuf, int off, int len) throws IOException
{
// TODO Auto-generated method stub
}
}

View File

@ -1,126 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.websocket.core.api.Extension;
import org.eclipse.jetty.websocket.core.api.ExtensionRegistry;
import org.eclipse.jetty.websocket.core.api.WebSocketException;
import org.eclipse.jetty.websocket.core.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.core.extensions.compress.PerMessageCompressionExtension;
import org.eclipse.jetty.websocket.core.extensions.compress.WebkitDeflateFrameExtension;
import org.eclipse.jetty.websocket.core.extensions.fragment.FragmentExtension;
import org.eclipse.jetty.websocket.core.extensions.identity.IdentityExtension;
import org.eclipse.jetty.websocket.core.protocol.ExtensionConfig;
public class WebSocketExtensionRegistry implements ExtensionRegistry
{
private Map<String, Class<? extends Extension>> registry;
private WebSocketPolicy policy;
private ByteBufferPool bufferPool;
public WebSocketExtensionRegistry(WebSocketPolicy policy, ByteBufferPool bufferPool)
{
this.policy = policy;
this.bufferPool = bufferPool;
this.registry = new HashMap<>();
this.registry.put("identity",IdentityExtension.class);
this.registry.put("fragment",FragmentExtension.class);
this.registry.put("x-webkit-deflate-frame",WebkitDeflateFrameExtension.class);
this.registry.put("permessage-compress",PerMessageCompressionExtension.class);
}
@Override
public boolean isAvailable(String name)
{
synchronized (registry)
{
return registry.containsKey(name);
}
}
@Override
public Iterator<Class<? extends Extension>> iterator()
{
List<Class<? extends Extension>> coll = new ArrayList<>();
synchronized (registry)
{
coll.addAll(registry.values());
return coll.iterator();
}
}
public Extension newInstance(ExtensionConfig config)
{
if (config == null)
{
return null;
}
String name = config.getName();
if (StringUtil.isBlank(name))
{
return null;
}
Class<? extends Extension> extClass = registry.get(name);
if (extClass == null)
{
return null;
}
try
{
Extension ext = extClass.newInstance();
ext.setConfig(config);
ext.setPolicy(policy);
ext.setBufferPool(bufferPool);
return ext;
}
catch (InstantiationException | IllegalAccessException e)
{
throw new WebSocketException("Cannot instantiate extension: " + extClass,e);
}
}
@Override
public void register(String name, Class<? extends Extension> extension)
{
synchronized (registry)
{
registry.put(name,extension);
}
}
@Override
public void unregister(String name)
{
synchronized (registry)
{
registry.remove(name);
}
}
}

View File

@ -1,160 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.compress;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.api.Extension;
import org.eclipse.jetty.websocket.core.protocol.ExtensionConfig;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
/**
* Per Message Compression extension for WebSocket.
* <p>
* Attempts to follow <a href="https://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-01">draft-ietf-hybi-permessage-compression-01</a>
*/
public class PerMessageCompressionExtension extends Extension
{
private static final Logger LOG = Log.getLogger(PerMessageCompressionExtension.class);
private CompressionMethod method;
@Override
public void incoming(final WebSocketFrame frame)
{
if (frame.isControlFrame() || !frame.isRsv1())
{
// Cannot modify incoming control frames or ones with RSV1 set.
super.incoming(frame);
return;
}
ByteBuffer data = frame.getPayload();
try
{
method.decompress().input(data);
while (!method.decompress().isDone())
{
ByteBuffer uncompressed = method.decompress().process();
if (uncompressed == null)
{
continue;
}
WebSocketFrame out = new WebSocketFrame(frame,uncompressed);
if (!method.decompress().isDone())
{
out.setFin(false);
}
nextIncoming(out);
}
// reset only at the end of a message.
if (frame.isFin())
{
method.decompress().end();
}
}
finally
{
// release original buffer (no longer needed)
getBufferPool().release(data);
}
}
/**
* Indicates use of RSV1 flag for indicating deflation is in use.
*/
@Override
public boolean isRsv1User()
{
return true;
}
@Override
public boolean isTextDataDecoder()
{
// this extension is responsible for text data frames
return true;
}
@Override
public <C> void output(C context, Callback<C> callback, final WebSocketFrame frame) throws IOException
{
if (frame.isControlFrame())
{
// skip, cannot compress control frames.
nextOutput(context,callback,frame);
return;
}
ByteBuffer data = frame.getPayload();
try
{
// deflate data
method.compress().input(data);
while (!method.compress().isDone())
{
ByteBuffer buf = method.compress().process();
WebSocketFrame out = new WebSocketFrame(frame,buf);
out.setRsv1(true);
if (!method.compress().isDone())
{
out.setFin(false);
nextOutputNoCallback(out);
}
else
{
nextOutput(context,callback,out);
}
}
// reset only at end of message
if (frame.isFin())
{
method.compress().end();
}
}
finally
{
// free original data buffer
getBufferPool().release(data);
}
}
@Override
public void setConfig(ExtensionConfig config)
{
super.setConfig(config);
String methodOptions = config.getParameter("method","deflate");
LOG.debug("Method requested: {}",methodOptions);
method = new DeflateCompressionMethod();
}
@Override
public String toString()
{
return String.format("%s[method=%s]",this.getClass().getSimpleName(),method);
}
}

View File

@ -1,157 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.compress;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.api.Extension;
import org.eclipse.jetty.websocket.core.protocol.ExtensionConfig;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
/**
* Implementation of the <a href="https://tools.ietf.org/id/draft-tyoshino-hybi-websocket-perframe-deflate-05.txt">x-webkit-deflate-frame</a> extension seen out
* in the wild.
*/
public class WebkitDeflateFrameExtension extends Extension
{
private static final Logger LOG = Log.getLogger(WebkitDeflateFrameExtension.class);
private DeflateCompressionMethod method;
@Override
public void incoming(WebSocketFrame frame)
{
if (frame.isControlFrame() || !frame.isRsv1())
{
// Cannot modify incoming control frames or ones with RSV1 set.
super.incoming(frame);
return;
}
LOG.debug("Decompressing Frame: {}",frame);
ByteBuffer data = frame.getPayload();
try
{
method.decompress().input(data);
while (!method.decompress().isDone())
{
ByteBuffer uncompressed = method.decompress().process();
WebSocketFrame out = new WebSocketFrame(frame,uncompressed);
if (!method.decompress().isDone())
{
out.setFin(false);
}
nextIncoming(out);
}
// reset on every frame.
method.decompress().end();
}
finally
{
// release original buffer (no longer needed)
getBufferPool().release(data);
}
}
/**
* Indicates use of RSV1 flag for indicating deflation is in use.
* <p>
* Also known as the "COMP" framing header bit
*/
@Override
public boolean isRsv1User()
{
return true;
}
/**
* Indicate that this extensions is now responsible for TEXT Data Frame compliance to the WebSocket spec.
*/
@Override
public boolean isTextDataDecoder()
{
return true;
}
@Override
public <C> void output(C context, Callback<C> callback, WebSocketFrame frame) throws IOException
{
if (frame.isControlFrame())
{
// skip, cannot compress control frames.
nextOutput(context,callback,frame);
return;
}
if (LOG.isDebugEnabled())
{
LOG.debug("output({}, {}, {})",context,callback,frame);
}
ByteBuffer data = frame.getPayload();
try
{
// deflate data
method.compress().input(data);
while (!method.compress().isDone())
{
ByteBuffer buf = method.compress().process();
WebSocketFrame out = new WebSocketFrame(frame,buf);
out.setRsv1(true);
if (!method.compress().isDone())
{
out.setFin(false);
nextOutputNoCallback(out);
}
else
{
nextOutput(context,callback,out);
}
}
// reset on every frame.
method.compress().end();
}
finally
{
// free original data buffer
getBufferPool().release(data);
}
}
@Override
public void setConfig(ExtensionConfig config)
{
super.setConfig(config);
method = new DeflateCompressionMethod();
}
@Override
public String toString()
{
return this.getClass().getSimpleName() + "[]";
}
}

View File

@ -1,98 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.extensions.fragment;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.websocket.core.api.Extension;
import org.eclipse.jetty.websocket.core.protocol.ExtensionConfig;
import org.eclipse.jetty.websocket.core.protocol.OpCode;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
public class FragmentExtension extends Extension
{
private int maxLength = -1;
@Override
public <C> void output(C context, Callback<C> callback, final WebSocketFrame frame) throws IOException
{
if (frame.isControlFrame())
{
// Cannot fragment Control Frames
nextOutput(context,callback,frame);
return;
}
int length = frame.getPayloadLength();
byte opcode = frame.getOpCode(); // original opcode
ByteBuffer payload = frame.getPayload().slice();
int originalLimit = payload.limit();
int currentPosition = payload.position();
if (maxLength <= 0)
{
// output original frame
nextOutput(context,callback,frame);
return;
}
boolean continuation = false;
// break apart payload based on maxLength rules
while (length > maxLength)
{
WebSocketFrame frag = new WebSocketFrame(frame);
frag.setOpCode(opcode);
frag.setFin(false); // always false here
frag.setContinuation(continuation);
payload.position(currentPosition);
payload.limit(Math.min(payload.position() + maxLength,originalLimit));
frag.setPayload(payload);
nextOutputNoCallback(frag);
length -= maxLength;
opcode = OpCode.CONTINUATION;
continuation = true;
currentPosition = payload.limit();
}
// write remaining
WebSocketFrame frag = new WebSocketFrame(frame);
frag.setOpCode(opcode);
frag.setFin(frame.isFin()); // use original fin
frag.setContinuation(continuation);
payload.position(currentPosition);
payload.limit(originalLimit);
frag.setPayload(payload);
nextOutput(context,callback,frag);
}
@Override
public void setConfig(ExtensionConfig config)
{
super.setConfig(config);
maxLength = config.getParameter("maxLength",maxLength);
}
}

View File

@ -1,90 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.io;
import java.io.IOException;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FutureCallback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.core.api.WebSocketException;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
/**
* Utility class to pipe {@link IncomingFrames} and {@link OutgoingFrames} around
*/
public class FramePipes
{
private static class In2Out implements IncomingFrames
{
private static final Logger LOG = Log.getLogger(In2Out.class);
private OutgoingFrames outgoing;
public In2Out(OutgoingFrames outgoing)
{
this.outgoing = outgoing;
}
@Override
public void incoming(WebSocketException e)
{
/* cannot send exception on */
}
@Override
public void incoming(WebSocketFrame frame)
{
try
{
this.outgoing.output(null,new FutureCallback<>(),frame);
}
catch (IOException e)
{
LOG.debug(e);
}
}
}
private static class Out2In implements OutgoingFrames
{
private IncomingFrames incoming;
public Out2In(IncomingFrames incoming)
{
this.incoming = incoming;
}
@Override
public <C> void output(C context, Callback<C> callback, WebSocketFrame frame) throws IOException
{
this.incoming.incoming(frame);
}
}
public static OutgoingFrames to(final IncomingFrames incoming)
{
return new Out2In(incoming);
}
public static IncomingFrames to(final OutgoingFrames outgoing)
{
return new In2Out(outgoing);
}
}

View File

@ -1,47 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.core.protocol;
import java.nio.ByteBuffer;
/**
* The immutable frame details.
* <p>
* Used by end user via @OnWebSocketFrame
*/
public interface Frame
{
public byte[] getMask();
public byte getOpCode();
public ByteBuffer getPayload();
public int getPayloadLength();
public boolean isFin();
public boolean isMasked();
public boolean isRsv1();
public boolean isRsv2();
public boolean isRsv3();
}

View File

@ -26,12 +26,12 @@ import java.util.Arrays;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.websocket.core.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.core.protocol.Generator;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.common.Generator;
import org.eclipse.jetty.websocket.common.OpCode;
import org.eclipse.jetty.websocket.common.Parser;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.core.protocol.IncomingFramesCapture;
import org.eclipse.jetty.websocket.core.protocol.OpCode;
import org.eclipse.jetty.websocket.core.protocol.Parser;
import org.eclipse.jetty.websocket.core.protocol.WebSocketFrame;
import org.junit.Assert;
import org.junit.Test;

Some files were not shown because too many files have changed in this diff Show More