Make sure the WebSocketClientHandshaker* work also with non Heap ChannelBuffers. See #602

This commit is contained in:
norman 2012-09-14 13:55:47 +02:00
parent 1ddc19bbca
commit d82b929e21
7 changed files with 78 additions and 35 deletions

View File

@ -17,9 +17,9 @@ package org.jboss.netty.handler.codec.http.websocketx;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Map;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
@ -48,7 +48,7 @@ import org.jboss.netty.handler.codec.http.HttpVersion;
*/
public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
private byte[] expectedChallengeResponseBytes;
private ChannelBuffer expectedChallengeResponseBytes;
/**
* Constructor with default values
@ -146,7 +146,7 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
System.arraycopy(number1Array, 0, challenge, 0, 4);
System.arraycopy(number2Array, 0, challenge, 4, 4);
System.arraycopy(key3, 0, challenge, 8, 8);
expectedChallengeResponseBytes = WebSocketUtil.md5(challenge);
expectedChallengeResponseBytes = WebSocketUtil.md5(ChannelBuffers.wrappedBuffer(challenge));
// Get path
URI wsURL = getWebSocketUrl();
@ -239,8 +239,8 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
+ response.getHeader(Names.CONNECTION));
}
byte[] challenge = response.getContent().array();
if (!Arrays.equals(challenge, expectedChallengeResponseBytes)) {
ChannelBuffer challenge = response.getContent();
if (challenge.equals(expectedChallengeResponseBytes)) {
throw new WebSocketHandshakeException("Invalid challenge");
}

View File

@ -18,6 +18,8 @@ package org.jboss.netty.handler.codec.http.websocketx;
import java.net.URI;
import java.util.Map;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
@ -127,11 +129,11 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
}
// Get 16 bit nonce and base 64 encode it
byte[] nonce = WebSocketUtil.randomBytes(16);
ChannelBuffer nonce = ChannelBuffers.wrappedBuffer(WebSocketUtil.randomBytes(16));
String key = WebSocketUtil.base64(nonce);
String acceptSeed = key + MAGIC_GUID;
byte[] sha1 = WebSocketUtil.sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII.name()));
ChannelBuffer sha1 = WebSocketUtil.sha1(ChannelBuffers.copiedBuffer(acceptSeed, CharsetUtil.US_ASCII));
expectedChallengeResponseString = WebSocketUtil.base64(sha1);
if (logger.isDebugEnabled()) {

View File

@ -18,6 +18,8 @@ package org.jboss.netty.handler.codec.http.websocketx;
import java.net.URI;
import java.util.Map;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
@ -126,11 +128,11 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
}
// Get 16 bit nonce and base 64 encode it
byte[] nonce = WebSocketUtil.randomBytes(16);
ChannelBuffer nonce = ChannelBuffers.wrappedBuffer(WebSocketUtil.randomBytes(16));
String key = WebSocketUtil.base64(nonce);
String acceptSeed = key + MAGIC_GUID;
byte[] sha1 = WebSocketUtil.sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII.name()));
ChannelBuffer sha1 = WebSocketUtil.sha1(ChannelBuffers.copiedBuffer(acceptSeed, CharsetUtil.US_ASCII));
expectedChallengeResponseString = WebSocketUtil.base64(sha1);
if (logger.isDebugEnabled()) {

View File

@ -173,8 +173,7 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
input.writeInt(a);
input.writeInt(b);
input.writeLong(c);
ChannelBuffer output = ChannelBuffers.wrappedBuffer(WebSocketUtil.md5(input.array()));
res.setContent(output);
res.setContent(WebSocketUtil.md5(input));
} else {
// Old Hixie 75 handshake method with no challenge:
res.addHeader(WEBSOCKET_ORIGIN, req.getHeader(ORIGIN));

View File

@ -20,6 +20,8 @@ import static org.jboss.netty.handler.codec.http.HttpVersion.*;
import java.io.UnsupportedEncodingException;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
@ -140,12 +142,8 @@ public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker {
throw new WebSocketHandshakeException("not a WebSocket request: missing key");
}
String acceptSeed = key + WEBSOCKET_08_ACCEPT_GUID;
byte[] sha1;
try {
sha1 = WebSocketUtil.sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII.name()));
} catch (UnsupportedEncodingException e) {
return Channels.failedFuture(channel, e);
}
ChannelBuffer sha1 = WebSocketUtil.sha1(ChannelBuffers.copiedBuffer(acceptSeed, CharsetUtil.US_ASCII));
String accept = WebSocketUtil.base64(sha1);
if (logger.isDebugEnabled()) {

View File

@ -20,6 +20,8 @@ import static org.jboss.netty.handler.codec.http.HttpVersion.*;
import java.io.UnsupportedEncodingException;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
@ -147,12 +149,7 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker {
throw new WebSocketHandshakeException("not a WebSocket request: missing key");
}
String acceptSeed = key + WEBSOCKET_13_ACCEPT_GUID;
byte[] sha1;
try {
sha1 = WebSocketUtil.sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII.name()));
} catch (UnsupportedEncodingException e) {
return Channels.failedFuture(channel, e);
}
ChannelBuffer sha1 = WebSocketUtil.sha1(ChannelBuffers.copiedBuffer(acceptSeed, CharsetUtil.US_ASCII));
String accept = WebSocketUtil.base64(sha1);
if (logger.isDebugEnabled()) {

View File

@ -29,12 +29,9 @@ import org.jboss.netty.util.CharsetUtil;
final class WebSocketUtil {
/**
* Performs an MD5 hash
*
* @param bytes
* Data to hash
* @return Hashed data
* @deprecated use {@link #md5(ChannelBuffer)}
*/
@Deprecated
static byte[] md5(byte[] bytes) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
@ -45,12 +42,30 @@ final class WebSocketUtil {
}
/**
* Performs an SHA-1 hash
* Performs an MD5 hash
*
* @param bytes
* Data to hash
* @param buffer
* buffer to hash
* @return Hashed data
*/
static ChannelBuffer md5(ChannelBuffer buffer) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
if (buffer.hasArray()) {
md.update(buffer.array(), buffer.readerIndex(), buffer.readableBytes());
} else {
md.update(buffer.toByteBuffer());
}
return ChannelBuffers.wrappedBuffer(md.digest());
} catch (NoSuchAlgorithmException e) {
throw new InternalError("MD5 not supported on this platform");
}
}
/**
* @deprecated use {@link #sha1(ChannelBuffer)}
*/
@Deprecated
static byte[] sha1(byte[] bytes) {
try {
MessageDigest md = MessageDigest.getInstance("SHA1");
@ -61,17 +76,47 @@ final class WebSocketUtil {
}
/**
* Base 64 encoding
* Performs an SHA-1 hash
*
* @param bytes
* Bytes to encode
* @return encoded string
* @param buffer
* buffer to hash
* @return Hashed data
*/
static ChannelBuffer sha1(ChannelBuffer buffer) {
try {
MessageDigest md = MessageDigest.getInstance("SHA1");
if (buffer.hasArray()) {
md.update(buffer.array(), buffer.readerIndex(), buffer.readableBytes());
} else {
md.update(buffer.toByteBuffer());
}
return ChannelBuffers.wrappedBuffer(md.digest());
} catch (NoSuchAlgorithmException e) {
throw new InternalError("SHA-1 not supported on this platform");
}
}
/**
* @deprecated use {@link #base64(ChannelBuffer)}
*/
@Deprecated
static String base64(byte[] bytes) {
ChannelBuffer hashed = ChannelBuffers.wrappedBuffer(bytes);
return Base64.encode(hashed).toString(CharsetUtil.UTF_8);
}
/**
* Base 64 encoding
*
* @param buffer
* Bytes to encode
* @return encoded string
*/
static String base64(ChannelBuffer buffer) {
return Base64.encode(buffer).toString(CharsetUtil.UTF_8);
}
/**
* Creates some random bytes
*