324369 Implement draft-ietf-hybi-thewebsocketprotocol-01
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@2245 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
f3c64a9c26
commit
1596451908
|
@ -94,6 +94,10 @@ public class WebSocketUpgradeTest extends TestCase
|
|||
public void onMessage(byte frame, byte[] data, int offset, int length)
|
||||
{
|
||||
}
|
||||
|
||||
public void onFragment(boolean more, byte opcode, byte[] data, int offset, int length)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -245,5 +249,9 @@ public class WebSocketUpgradeTest extends TestCase
|
|||
{
|
||||
_outbound.sendMessage(msg);
|
||||
}
|
||||
|
||||
public void onFragment(boolean more, byte opcode, byte[] data, int offset, int length)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,16 +7,17 @@ public interface WebSocket
|
|||
public final byte LENGTH_FRAME=(byte)0x80;
|
||||
public final byte SENTINEL_FRAME=(byte)0x00;
|
||||
void onConnect(Outbound outbound);
|
||||
void onMessage(byte frame,String data);
|
||||
void onMessage(byte frame,byte[] data, int offset, int length);
|
||||
void onMessage(byte opcode,String data);
|
||||
void onFragment(boolean more,byte opcode,byte[] data, int offset, int length);
|
||||
void onMessage(byte opcode,byte[] data, int offset, int length);
|
||||
void onDisconnect();
|
||||
|
||||
public interface Outbound
|
||||
{
|
||||
void sendMessage(String data) throws IOException;
|
||||
void sendMessage(byte frame,String data) throws IOException;
|
||||
void sendMessage(byte frame,byte[] data) throws IOException;
|
||||
void sendMessage(byte frame,byte[] data, int offset, int length) throws IOException;
|
||||
void sendMessage(byte opcode,String data) throws IOException;
|
||||
void sendMessage(byte opcode,byte[] data, int offset, int length) throws IOException;
|
||||
void sendFragment(boolean more,byte opcode,byte[] data, int offset, int length) throws IOException;
|
||||
void disconnect();
|
||||
boolean isOpen();
|
||||
}
|
||||
|
|
|
@ -3,10 +3,7 @@ package org.eclipse.jetty.websocket;
|
|||
import java.io.IOException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.zip.Checksum;
|
||||
|
||||
import org.eclipse.jetty.http.HttpParser;
|
||||
import org.eclipse.jetty.http.security.Credential.MD5;
|
||||
import org.eclipse.jetty.io.AsyncEndPoint;
|
||||
import org.eclipse.jetty.io.Buffer;
|
||||
import org.eclipse.jetty.io.ByteArrayBuffer;
|
||||
|
@ -14,10 +11,8 @@ import org.eclipse.jetty.io.Connection;
|
|||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
|
||||
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.Utf8StringBuilder;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.thread.Timeout;
|
||||
|
||||
public class WebSocketConnection implements Connection, WebSocket.Outbound
|
||||
{
|
||||
|
@ -51,6 +46,7 @@ public class WebSocketConnection implements Connection, WebSocket.Outbound
|
|||
_websocket = websocket;
|
||||
final WebSocketParser.FrameHandler handler = new WebSocketParser.FrameHandler()
|
||||
{
|
||||
boolean _fragmented=false;
|
||||
Utf8StringBuilder _utf8 = new Utf8StringBuilder();
|
||||
|
||||
public void onFrame(boolean more, byte flags, byte opcode, Buffer buffer)
|
||||
|
@ -62,23 +58,38 @@ public class WebSocketConnection implements Connection, WebSocket.Outbound
|
|||
if (opcode==0)
|
||||
{
|
||||
if (more)
|
||||
{
|
||||
_utf8.append(buffer.array(),buffer.getIndex(),buffer.length());
|
||||
else if (_utf8.length()==0)
|
||||
_websocket.onMessage(opcode,buffer.toString("utf-8"));
|
||||
else
|
||||
_fragmented=true;
|
||||
}
|
||||
else if (_fragmented)
|
||||
{
|
||||
_utf8.append(buffer.array(),buffer.getIndex(),buffer.length());
|
||||
_websocket.onMessage(opcode,_utf8.toString());
|
||||
_utf8.reset();
|
||||
_fragmented=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_websocket.onMessage(opcode,buffer.toString("utf-8"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (more)
|
||||
throw new IllegalStateException("not implemented");
|
||||
{
|
||||
_websocket.onFragment(true,opcode,array,buffer.getIndex(),buffer.length());
|
||||
}
|
||||
else if (_fragmented)
|
||||
{
|
||||
_websocket.onFragment(false,opcode,array,buffer.getIndex(),buffer.length());
|
||||
}
|
||||
else
|
||||
{
|
||||
_websocket.onMessage(opcode,array,buffer.getIndex(),buffer.length());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(ThreadDeath th)
|
||||
{
|
||||
throw th;
|
||||
|
@ -262,14 +273,17 @@ public class WebSocketConnection implements Connection, WebSocket.Outbound
|
|||
_idle.access(_endp);
|
||||
}
|
||||
|
||||
public void sendMessage(byte frame, byte[] content) throws IOException
|
||||
public void sendMessage(byte opcode, byte[] content, int offset, int length) throws IOException
|
||||
{
|
||||
sendMessage(frame, content, 0, content.length);
|
||||
_generator.addFrame(opcode,content,offset,length,_endp.getMaxIdleTime());
|
||||
_generator.flush();
|
||||
checkWriteable();
|
||||
_idle.access(_endp);
|
||||
}
|
||||
|
||||
public void sendMessage(byte frame, byte[] content, int offset, int length) throws IOException
|
||||
public void sendFragment(boolean more,byte opcode, byte[] content, int offset, int length) throws IOException
|
||||
{
|
||||
_generator.addFrame(frame,content,offset,length,_endp.getMaxIdleTime());
|
||||
_generator.addFragment(more,opcode,content,offset,length,_endp.getMaxIdleTime());
|
||||
_generator.flush();
|
||||
checkWriteable();
|
||||
_idle.access(_endp);
|
||||
|
|
|
@ -13,6 +13,6 @@ public interface WebSocketGenerator
|
|||
boolean isBufferEmpty();
|
||||
void addFrame(byte opcode, String content, int maxIdleTime) throws IOException;
|
||||
void addFrame(byte opcode, byte[] content, int offset, int length, int maxIdleTime) throws IOException;
|
||||
void addFrame(byte opcode, byte[] content, int maxIdleTime)throws IOException;
|
||||
void addFragment(boolean more,byte opcode, byte[] content, int offset, int length, int maxIdleTime) throws IOException;
|
||||
int flush(int maxIdleTime) throws IOException;
|
||||
}
|
||||
|
|
|
@ -29,11 +29,6 @@ public class WebSocketGeneratorD00 implements WebSocketGenerator
|
|||
_endp=endp;
|
||||
}
|
||||
|
||||
public synchronized void addFrame(byte frame,byte[] content, int blockFor) throws IOException
|
||||
{
|
||||
addFrame(frame,content,0,content.length,blockFor);
|
||||
}
|
||||
|
||||
public synchronized void addFrame(byte opcode,byte[] content, int offset, int length, int blockFor) throws IOException
|
||||
{
|
||||
if (_buffer==null)
|
||||
|
@ -165,4 +160,11 @@ public class WebSocketGeneratorD00 implements WebSocketGenerator
|
|||
return _buffer==null || _buffer.length()==0;
|
||||
}
|
||||
|
||||
public void addFragment(boolean more, byte opcode, byte[] content, int offset, int length, int maxIdleTime) throws IOException
|
||||
{
|
||||
if (more)
|
||||
throw new UnsupportedOperationException("fragmented");
|
||||
addFrame(opcode,content,offset,length,maxIdleTime);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,7 +36,13 @@ public class WebSocketGeneratorD01 implements WebSocketGenerator
|
|||
addFrame(opcode,content,0,content.length,blockFor);
|
||||
}
|
||||
|
||||
|
||||
public synchronized void addFrame(byte opcode,byte[] content, int offset, int length, int blockFor) throws IOException
|
||||
{
|
||||
addFragment(false,opcode,content,offset,length,blockFor);
|
||||
}
|
||||
|
||||
public synchronized void addFragment(boolean more, byte opcode, byte[] content, int offset, int length, int blockFor) throws IOException
|
||||
{
|
||||
if (_buffer==null)
|
||||
_buffer=_buffers.getDirectBuffer();
|
||||
|
@ -55,6 +61,8 @@ public class WebSocketGeneratorD01 implements WebSocketGenerator
|
|||
fragment=_buffer.capacity()-10;
|
||||
bufferPut((byte)(0x80|opcode), blockFor);
|
||||
}
|
||||
else if (more)
|
||||
bufferPut((byte)(0x80|opcode), blockFor);
|
||||
else
|
||||
bufferPut(opcode, blockFor);
|
||||
|
||||
|
@ -178,4 +186,5 @@ public class WebSocketGeneratorD01 implements WebSocketGenerator
|
|||
{
|
||||
return _buffer==null || _buffer.length()==0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ public class WebSocketGeneratorD00Test
|
|||
for (int i=0;i<b.length;i++)
|
||||
b[i]=(byte)('0'+(i%10));
|
||||
|
||||
_generator.addFrame((byte)0xf,b,0);
|
||||
_generator.addFrame((byte)0xf,b,0,b.length,0);
|
||||
|
||||
_generator.flush();
|
||||
assertEquals(0x0f,_out.get());
|
||||
|
@ -74,7 +74,7 @@ public class WebSocketGeneratorD00Test
|
|||
for (int i=0;i<b.length;i++)
|
||||
b[i]=(byte)('0'+(i%10));
|
||||
|
||||
_generator.addFrame((byte)0xf,b,0);
|
||||
_generator.addFrame((byte)0xf,b,0,b.length,0);
|
||||
|
||||
_generator.flush();
|
||||
assertEquals(0x8f,_out.get()&0xff);
|
||||
|
|
|
@ -53,7 +53,9 @@ public class WebSocketGeneratorD01Test
|
|||
@Test
|
||||
public void testOneBuffer() throws Exception
|
||||
{
|
||||
_generator.addFrame((byte)0x84,"Hell\uFF4F W\uFF4Frld".getBytes(StringUtil.__UTF8),0);
|
||||
String string = "Hell\uFF4F W\uFF4Frld";
|
||||
byte[] bytes=string.getBytes(StringUtil.__UTF8);
|
||||
_generator.addFrame((byte)0x84,bytes,0,bytes.length,0);
|
||||
_generator.flush();
|
||||
assertEquals(0x84,0xff&_out.get());
|
||||
assertEquals(15,0xff&_out.get());
|
||||
|
@ -81,7 +83,7 @@ public class WebSocketGeneratorD01Test
|
|||
for (int i=0;i<b.length;i++)
|
||||
b[i]=(byte)('0'+(i%10));
|
||||
|
||||
_generator.addFrame((byte)0x85,b,0);
|
||||
_generator.addFrame((byte)0x85,b,0,b.length,0);
|
||||
|
||||
_generator.flush();
|
||||
assertEquals(0x85,0xff&_out.get());
|
||||
|
|
|
@ -126,6 +126,10 @@ public class WebSocketLoadTest
|
|||
}
|
||||
}
|
||||
|
||||
public void onFragment(boolean more, byte opcode, byte[] data, int offset, int length)
|
||||
{
|
||||
}
|
||||
|
||||
public void onMessage(byte frame, byte[] data, int offset, int length)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ public class WebSocketMessageTest
|
|||
for (int i = 0; i < 64 * 1024 / text.length(); ++i)
|
||||
message.append(text);
|
||||
byte[] data = message.toString().getBytes("UTF-8");
|
||||
_serverWebSocket.outbound.sendMessage(WebSocket.LENGTH_FRAME, data);
|
||||
_serverWebSocket.outbound.sendMessage(WebSocket.LENGTH_FRAME, data,0,data.length);
|
||||
|
||||
// Length of the message is 65536, so the length will be encoded as 0x84 0x80 0x00
|
||||
int frame = input.read();
|
||||
|
@ -194,5 +194,9 @@ public class WebSocketMessageTest
|
|||
public void onDisconnect()
|
||||
{
|
||||
}
|
||||
|
||||
public void onFragment(boolean more, byte opcode, byte[] data, int offset, int length)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,7 +117,6 @@ public class WebSocketParserD01Test
|
|||
string += ". The end.";
|
||||
|
||||
byte[] bytes = string.getBytes("UTF-8");
|
||||
System.err.println(Long.toHexString(bytes.length));
|
||||
|
||||
in.put((byte)0x00);
|
||||
in.put((byte)0x7F);
|
||||
|
|
|
@ -137,7 +137,6 @@ public class WebSocketTest
|
|||
ByteArrayBuffer out = _connector.getResponses(buffer,true);
|
||||
|
||||
String response = StringUtil.printable(out.asArray());
|
||||
System.err.println(response);
|
||||
|
||||
assertTrue(response.startsWith("HTTP/1.1 101 Web Socket Protocol Handshake"));
|
||||
assertTrue(response.contains("Upgrade: WebSocket"));
|
||||
|
@ -181,5 +180,9 @@ public class WebSocketTest
|
|||
{
|
||||
_disconnected=true;
|
||||
}
|
||||
|
||||
public void onFragment(boolean more, byte opcode, byte[] data, int offset, int length)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,6 +77,10 @@ public class WebSocketTestServer extends Server
|
|||
{
|
||||
_webSockets.remove(this);
|
||||
}
|
||||
|
||||
public void onFragment(boolean more, byte opcode, byte[] data, int offset, int length)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
|
|
|
@ -74,5 +74,9 @@ public class WebSocketChatServlet extends WebSocketServlet
|
|||
// Log.info(this+" onDisconnect");
|
||||
_members.remove(this);
|
||||
}
|
||||
|
||||
public void onFragment(boolean more, byte opcode, byte[] data, int offset, int length)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue