Overall clean-up on socksx package

- SocksV[45] -> Socks[45]
- Make encodeAsByteBuf package private with some hassle
- Split SocksMessageEncoder into Socks4MessageEncoder and
  Socks5MessageEncoder, and remove the original
- Remove lazy singleton instantiation; we don't need it.
- Remove the deprecated methods
- Fix Javadoc errors
This commit is contained in:
Trustin Lee 2014-08-14 16:30:36 -07:00
parent a242224646
commit d92875402d
67 changed files with 668 additions and 655 deletions

View File

@ -18,4 +18,3 @@
* Encoder, decoder and their related message types for Socks. * Encoder, decoder and their related message types for Socks.
*/ */
package io.netty.handler.codec.socks; package io.netty.handler.codec.socks;
// TODO: Combine decoders into one.

View File

@ -15,16 +15,10 @@
*/ */
package io.netty.handler.codec.socksx; package io.netty.handler.codec.socksx;
import io.netty.buffer.ByteBuf;
/** /**
* An abstract class that defines a SocksMessage, providing common properties for * An abstract class that defines a SocksMessage, providing common properties for
* {@link SocksV5Request} and {@link SocksV5Response}. * {@link SocksRequest} and {@link SocksResponse}.
*
* @see SocksV5Request
* @see SocksV5Response
*/ */
public abstract class SocksMessage { public abstract class SocksMessage {
private final SocksMessageType type; private final SocksMessageType type;
private final SocksProtocolVersion protocolVersion; private final SocksProtocolVersion protocolVersion;
@ -57,10 +51,4 @@ public abstract class SocksMessage {
public SocksProtocolVersion protocolVersion() { public SocksProtocolVersion protocolVersion() {
return protocolVersion; return protocolVersion;
} }
/**
* @deprecated Do not use; this method was intended for an internal use only.
*/
@Deprecated
public abstract void encodeAsByteBuf(ByteBuf byteBuf);
} }

View File

@ -27,14 +27,6 @@ public enum SocksProtocolVersion {
this.b = b; this.b = b;
} }
/**
* @deprecated Use {@link #valueOf(byte)} instead.
*/
@Deprecated
public static SocksProtocolVersion fromByte(byte b) {
return valueOf(b);
}
public static SocksProtocolVersion valueOf(byte b) { public static SocksProtocolVersion valueOf(byte b) {
for (SocksProtocolVersion code : values()) { for (SocksProtocolVersion code : values()) {
if (code.b == b) { if (code.b == b) {

View File

@ -16,18 +16,12 @@
package io.netty.handler.codec.socksx; package io.netty.handler.codec.socksx;
import io.netty.handler.codec.socksx.v4.Socks4Request;
import io.netty.handler.codec.socksx.v5.Socks5Request;
/** /**
* An abstract class that defines a SocksRequest, providing common properties for * An abstract class that defines a SOCKS request, providing common properties for
* {@link SocksV5InitRequest}, * {@link Socks4Request} and {@link Socks5Request}.
* {@link SocksV5AuthRequest},
* {@link SocksV5CmdRequest}
* and {@link UnknownSocksV5Request}.
*
* @see io.netty.handler.codec.socks.SocksInitRequest
* @see io.netty.handler.codec.socks.SocksAuthRequest
* @see io.netty.handler.codec.socks.SocksCmdRequest
* @see io.netty.handler.codec.socks.UnknownSocksRequest
*/ */
public abstract class SocksRequest extends SocksMessage { public abstract class SocksRequest extends SocksMessage {

View File

@ -15,6 +15,13 @@
*/ */
package io.netty.handler.codec.socksx; package io.netty.handler.codec.socksx;
import io.netty.handler.codec.socksx.v4.Socks4Response;
import io.netty.handler.codec.socksx.v5.Socks5Response;
/**
* An abstract class that defines a SOCKS response, providing common properties for
* {@link Socks4Response} and {@link Socks5Response}.
*/
public abstract class SocksResponse extends SocksMessage { public abstract class SocksResponse extends SocksMessage {
protected SocksResponse(SocksProtocolVersion protocolVersion) { protected SocksResponse(SocksProtocolVersion protocolVersion) {
super(protocolVersion, SocksMessageType.RESPONSE); super(protocolVersion, SocksMessageType.RESPONSE);

View File

@ -15,6 +15,6 @@
*/ */
/** /**
* Encoder, decoder and their related message types for Socks. * Encoder, decoder and their related message types for SOCKS protocol.
*/ */
package io.netty.handler.codec.socksx; package io.netty.handler.codec.socksx;

View File

@ -18,26 +18,24 @@ package io.netty.handler.codec.socksx.v4;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import io.netty.util.NetUtil; import io.netty.util.NetUtil;
import io.netty.util.internal.SystemPropertyUtil;
import java.net.IDN; import java.net.IDN;
/** /**
* An socksv4a cmd request. * An socksv4a cmd request.
* *
* @see SocksV4Response * @see Socks4Response
* @see SocksV4CmdRequestDecoder * @see Socks4CmdRequestDecoder
*/ */
public final class Socks4CmdRequest extends Socks4Request {
public final class SocksV4CmdRequest extends SocksV4Request {
private final String userId; private final String userId;
private final SocksV4CmdType cmdType; private final Socks4CmdType cmdType;
private final String host; private final String host;
private final int port; private final int port;
private static final byte[] IPv4_DOMAIN_MARKER = {0x00, 0x00, 0x00, 0x01}; private static final byte[] IPv4_DOMAIN_MARKER = {0x00, 0x00, 0x00, 0x01};
public SocksV4CmdRequest(String userId, SocksV4CmdType cmdType, String host, int port) { public Socks4CmdRequest(String userId, Socks4CmdType cmdType, String host, int port) {
if (userId == null) { if (userId == null) {
throw new NullPointerException("username"); throw new NullPointerException("username");
} }
@ -56,48 +54,48 @@ public final class SocksV4CmdRequest extends SocksV4Request {
this.port = port; this.port = port;
} }
public SocksV4CmdRequest(SocksV4CmdType cmdType, String host, int port) { public Socks4CmdRequest(Socks4CmdType cmdType, String host, int port) {
this("", cmdType, host, port); this("", cmdType, host, port);
} }
/** /**
* Returns the {@link SocksV4CmdType} of this {@link SocksV4Request} * Returns the {@link Socks4CmdType} of this {@link Socks4Request}
* *
* @return The {@link SocksV4CmdType} of this {@link SocksV4Request} * @return The {@link Socks4CmdType} of this {@link Socks4Request}
*/ */
public SocksV4CmdType cmdType() { public Socks4CmdType cmdType() {
return cmdType; return cmdType;
} }
/** /**
* Returns host that is used as a parameter in {@link SocksV4CmdType} * Returns host that is used as a parameter in {@link Socks4CmdType}
* *
* @return host that is used as a parameter in {@link SocksV4CmdType} * @return host that is used as a parameter in {@link Socks4CmdType}
*/ */
public String host() { public String host() {
return IDN.toUnicode(host); return IDN.toUnicode(host);
} }
/** /**
* Returns userId that is used as a parameter in {@link SocksV4CmdType} * Returns userId that is used as a parameter in {@link Socks4CmdType}
* *
* @return userId that is used as a parameter in {@link SocksV4CmdType} * @return userId that is used as a parameter in {@link Socks4CmdType}
*/ */
public String userId() { public String userId() {
return userId; return userId;
} }
/** /**
* Returns port that is used as a parameter in {@link SocksV4CmdType} * Returns port that is used as a parameter in {@link Socks4CmdType}
* *
* @return port that is used as a parameter in {@link SocksV4CmdType} * @return port that is used as a parameter in {@link Socks4CmdType}
*/ */
public int port() { public int port() {
return port; return port;
} }
@Override @Override
public void encodeAsByteBuf(ByteBuf byteBuf) { void encodeAsByteBuf(ByteBuf byteBuf) {
byteBuf.writeByte(protocolVersion().byteValue()); byteBuf.writeByte(protocolVersion().byteValue());
byteBuf.writeByte(cmdType.byteValue()); byteBuf.writeByte(cmdType.byteValue());
byteBuf.writeShort(port); byteBuf.writeShort(port);

View File

@ -19,29 +19,27 @@ import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.ReplayingDecoder;
import io.netty.handler.codec.socksx.SocksProtocolVersion; import io.netty.handler.codec.socksx.SocksProtocolVersion;
import io.netty.handler.codec.socksx.v4.SocksV4CmdRequestDecoder.State; import io.netty.handler.codec.socksx.v4.Socks4CmdRequestDecoder.State;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import io.netty.util.internal.SystemPropertyUtil;
import java.util.List; import java.util.List;
/** /**
* Decodes {@link ByteBuf}s into {@link SocksV4CmdRequest}. * Decodes {@link ByteBuf}s into {@link Socks4CmdRequest}.
* Before returning SocksRequest decoder removes itself from pipeline. * Before returning SocksRequest decoder removes itself from pipeline.
*/ */
public class SocksV4CmdRequestDecoder extends ReplayingDecoder<State> { public class Socks4CmdRequestDecoder extends ReplayingDecoder<State> {
private static final String name = "SOCKS_CMD_REQUEST_DECODER";
private SocksProtocolVersion version; private SocksProtocolVersion version;
private SocksV4CmdType cmdType; private Socks4CmdType cmdType;
@SuppressWarnings("UnusedDeclaration") @SuppressWarnings("UnusedDeclaration")
private byte reserved; private byte reserved;
private String host; private String host;
private int port; private int port;
private String userId; private String userId;
private SocksV4Request msg = UnknownSocksV4Request.getInstance(); private Socks4Request msg = UnknownSocks4Request.INSTANCE;
public SocksV4CmdRequestDecoder() { public Socks4CmdRequestDecoder() {
super(State.CHECK_PROTOCOL_VERSION); super(State.CHECK_PROTOCOL_VERSION);
} }
@ -56,9 +54,9 @@ public class SocksV4CmdRequestDecoder extends ReplayingDecoder<State> {
checkpoint(State.READ_CMD_HEADER); checkpoint(State.READ_CMD_HEADER);
} }
case READ_CMD_HEADER: { case READ_CMD_HEADER: {
cmdType = SocksV4CmdType.valueOf(byteBuf.readByte()); cmdType = Socks4CmdType.valueOf(byteBuf.readByte());
port = byteBuf.readUnsignedShort(); port = byteBuf.readUnsignedShort();
host = SocksV4CommonUtils.intToIp(byteBuf.readInt()); host = Socks4CommonUtils.intToIp(byteBuf.readInt());
checkpoint(State.READ_CMD_USERID); checkpoint(State.READ_CMD_USERID);
} }
case READ_CMD_USERID: { case READ_CMD_USERID: {
@ -67,17 +65,17 @@ public class SocksV4CmdRequestDecoder extends ReplayingDecoder<State> {
} }
case READ_CMD_DOMAIN: { case READ_CMD_DOMAIN: {
// Check for Socks4a protocol marker 0,0,0,x // Check for Socks4a protocol marker 0,0,0,x
if (!host.equals("0.0.0.0") && host.startsWith("0.0.0.")) { if (!"0.0.0.0".equals(host) && host.startsWith("0.0.0.")) {
host = readNullTerminatedString(byteBuf); host = readNullTerminatedString(byteBuf);
} }
msg = new SocksV4CmdRequest(userId, cmdType, host, port); msg = new Socks4CmdRequest(userId, cmdType, host, port);
} }
} }
ctx.pipeline().remove(this); ctx.pipeline().remove(this);
out.add(msg); out.add(msg);
} }
private static String readNullTerminatedString(ByteBuf byteBuf) throws Exception { private static String readNullTerminatedString(ByteBuf byteBuf) throws Exception {
byte NULL_BYTE = (byte) 0x00; byte NULL_BYTE = 0x00;
// Could be used for DoS // Could be used for DoS
String string = byteBuf.readBytes(byteBuf.bytesBefore(NULL_BYTE)).toString(CharsetUtil.US_ASCII); String string = byteBuf.readBytes(byteBuf.bytesBefore(NULL_BYTE)).toString(CharsetUtil.US_ASCII);
// Read NULL-byte // Read NULL-byte

View File

@ -23,18 +23,18 @@ import java.net.IDN;
/** /**
* A socks cmd response. * A socks cmd response.
* *
* @see SocksV4CmdRequest * @see Socks4CmdRequest
* @see SocksV4CmdResponseDecoder * @see Socks4CmdResponseDecoder
*/ */
public final class SocksV4CmdResponse extends SocksV4Response { public final class Socks4CmdResponse extends Socks4Response {
private final SocksV4CmdStatus cmdStatus; private final Socks4CmdStatus cmdStatus;
private final String host; private final String host;
private final int port; private final int port;
// All arrays are initialized on construction time to 0/false/null remove array Initialization // All arrays are initialized on construction time to 0/false/null remove array Initialization
private static final byte[] IPv4_HOSTNAME_ZEROED = { 0x00, 0x00, 0x00, 0x00 }; private static final byte[] IPv4_HOSTNAME_ZEROED = { 0x00, 0x00, 0x00, 0x00 };
public SocksV4CmdResponse(SocksV4CmdStatus cmdStatus) { public Socks4CmdResponse(Socks4CmdStatus cmdStatus) {
this(cmdStatus, null, 0); this(cmdStatus, null, 0);
} }
@ -44,13 +44,13 @@ public final class SocksV4CmdResponse extends SocksV4Response {
* @param cmdStatus status of the response * @param cmdStatus status of the response
* @param host host (BND.ADDR field) is address that server used when connecting to the target host. * @param host host (BND.ADDR field) is address that server used when connecting to the target host.
* When null a value of 4/8 0x00 octets will be used for IPv4/IPv6 and a single 0x00 byte will be * When null a value of 4/8 0x00 octets will be used for IPv4/IPv6 and a single 0x00 byte will be
* used for domain addressType. Value is converted to ASCII using {@link java.net.IDN#toASCII(String)}. * used for domain addressType. Value is converted to ASCII using {@link IDN#toASCII(String)}.
* @param port port (BND.PORT field) that the server assigned to connect to the target host * @param port port (BND.PORT field) that the server assigned to connect to the target host
* @throws NullPointerException in case cmdStatus or addressType are missing * @throws NullPointerException in case cmdStatus or addressType are missing
* @throws IllegalArgumentException in case host or port cannot be validated * @throws IllegalArgumentException in case host or port cannot be validated
* @see java.net.IDN#toASCII(String) * @see IDN#toASCII(String)
*/ */
public SocksV4CmdResponse(SocksV4CmdStatus cmdStatus, String host, int port) { public Socks4CmdResponse(Socks4CmdStatus cmdStatus, String host, int port) {
if (cmdStatus == null) { if (cmdStatus == null) {
throw new NullPointerException("cmdStatus"); throw new NullPointerException("cmdStatus");
} }
@ -68,20 +68,20 @@ public final class SocksV4CmdResponse extends SocksV4Response {
} }
/** /**
* Returns the {@link SocksV4CmdStatus} of this {@link SocksV4Response} * Returns the {@link Socks4CmdStatus} of this {@link Socks4Response}
* *
* @return The {@link SocksV4CmdStatus} of this {@link SocksV4Response} * @return The {@link Socks4CmdStatus} of this {@link Socks4Response}
*/ */
public SocksV4CmdStatus cmdStatus() { public Socks4CmdStatus cmdStatus() {
return cmdStatus; return cmdStatus;
} }
/** /**
* Returns host that is used as a parameter in {@link io.netty.handler.codec.socks.v4.SocksV4CmdType}. * Returns host that is used as a parameter in {@link Socks4CmdType}.
* Host (BND.ADDR field in response) is address that server used when connecting to the target host. * Host (BND.ADDR field in response) is address that server used when connecting to the target host.
* This is typically different from address which client uses to connect to the SOCKS server. * This is typically different from address which client uses to connect to the SOCKS server.
* *
* @return host that is used as a parameter in {@link io.netty.handler.codec.socks.v4.SocksV4CmdType} * @return host that is used as a parameter in {@link Socks4CmdType}
* or null when there was no host specified during response construction * or null when there was no host specified during response construction
*/ */
public String host() { public String host() {
@ -93,10 +93,10 @@ public final class SocksV4CmdResponse extends SocksV4Response {
} }
/** /**
* Returns port that is used as a parameter in {@link io.netty.handler.codec.socks.v4.SocksV4CmdType}. * Returns port that is used as a parameter in {@link Socks4CmdType}.
* Port (BND.PORT field in response) is port that the server assigned to connect to the target host. * Port (BND.PORT field in response) is port that the server assigned to connect to the target host.
* *
* @return port that is used as a parameter in {@link io.netty.handler.codec.socks.v4.SocksV4CmdType} * @return port that is used as a parameter in {@link Socks4CmdType}
*/ */
public int port() { public int port() {
return port; return port;

View File

@ -18,27 +18,23 @@ package io.netty.handler.codec.socksx.v4;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.ReplayingDecoder;
import io.netty.handler.codec.socks.SocksProtocolVersion; import io.netty.handler.codec.socksx.v4.Socks4CmdResponseDecoder.State;
import io.netty.handler.codec.socksx.v4.SocksV4CmdResponseDecoder.State;
import io.netty.util.CharsetUtil;
import java.util.List; import java.util.List;
/** /**
* Decodes {@link ByteBuf}s into {@link SocksV4CmdResponse}. * Decodes {@link ByteBuf}s into {@link Socks4CmdResponse}.
* Before returning SocksResponse decoder removes itself from pipeline. * Before returning SocksResponse decoder removes itself from pipeline.
*/ */
public class SocksV4CmdResponseDecoder extends ReplayingDecoder<State> { public class Socks4CmdResponseDecoder extends ReplayingDecoder<State> {
private static final String name = "SOCKS_CMD_RESPONSE_DECODER";
private SocksProtocolVersion version; private Socks4CmdStatus cmdStatus;
private SocksV4CmdStatus cmdStatus;
private String host; private String host;
private int port; private int port;
private SocksV4Response msg = UnknownSocksV4Response.getInstance(); private Socks4Response msg = UnknownSocks4Response.INSTANCE;
public SocksV4CmdResponseDecoder() { public Socks4CmdResponseDecoder() {
super(State.CHECK_NULL_BYTE); super(State.CHECK_NULL_BYTE);
} }
@ -52,13 +48,13 @@ public class SocksV4CmdResponseDecoder extends ReplayingDecoder<State> {
checkpoint(State.READ_CMD_HEADER); checkpoint(State.READ_CMD_HEADER);
} }
case READ_CMD_HEADER: { case READ_CMD_HEADER: {
cmdStatus = SocksV4CmdStatus.valueOf(byteBuf.readByte()); cmdStatus = Socks4CmdStatus.valueOf(byteBuf.readByte());
checkpoint(State.READ_CMD_ADDRESS); checkpoint(State.READ_CMD_ADDRESS);
} }
case READ_CMD_ADDRESS: { case READ_CMD_ADDRESS: {
port = byteBuf.readUnsignedShort(); port = byteBuf.readUnsignedShort();
host = SocksV4CommonUtils.intToIp(byteBuf.readInt()); host = Socks4CommonUtils.intToIp(byteBuf.readInt());
msg = new SocksV4CmdResponse(cmdStatus, host, port); msg = new Socks4CmdResponse(cmdStatus, host, port);
} }
} }
ctx.pipeline().remove(this); ctx.pipeline().remove(this);

View File

@ -15,7 +15,7 @@
*/ */
package io.netty.handler.codec.socksx.v4; package io.netty.handler.codec.socksx.v4;
public enum SocksV4CmdStatus { public enum Socks4CmdStatus {
SUCCESS((byte) 0x5a), SUCCESS((byte) 0x5a),
REJECTED_OR_FAILED((byte) 0x5b), REJECTED_OR_FAILED((byte) 0x5b),
IDENTD_UNREACHABLE((byte) 0x5c), IDENTD_UNREACHABLE((byte) 0x5c),
@ -24,12 +24,12 @@ public enum SocksV4CmdStatus {
private final byte b; private final byte b;
SocksV4CmdStatus(byte b) { Socks4CmdStatus(byte b) {
this.b = b; this.b = b;
} }
public static SocksV4CmdStatus valueOf(byte b) { public static Socks4CmdStatus valueOf(byte b) {
for (SocksV4CmdStatus code : values()) { for (Socks4CmdStatus code : values()) {
if (code.b == b) { if (code.b == b) {
return code; return code;
} }

View File

@ -15,19 +15,19 @@
*/ */
package io.netty.handler.codec.socksx.v4; package io.netty.handler.codec.socksx.v4;
public enum SocksV4CmdType { public enum Socks4CmdType {
CONNECT((byte) 0x01), CONNECT((byte) 0x01),
BIND((byte) 0x02), BIND((byte) 0x02),
UNKNOWN((byte) 0xff); UNKNOWN((byte) 0xff);
private final byte b; private final byte b;
SocksV4CmdType(byte b) { Socks4CmdType(byte b) {
this.b = b; this.b = b;
} }
public static SocksV4CmdType valueOf(byte b) { public static Socks4CmdType valueOf(byte b) {
for (SocksV4CmdType code : values()) { for (Socks4CmdType code : values()) {
if (code.b == b) { if (code.b == b) {
return code; return code;
} }

View File

@ -16,7 +16,8 @@
package io.netty.handler.codec.socksx.v4; package io.netty.handler.codec.socksx.v4;
import io.netty.util.internal.StringUtil; import io.netty.util.internal.StringUtil;
public final class SocksV4CommonUtils { final class Socks4CommonUtils {
private static final int SECOND_ADDRESS_OCTET_SHIFT = 16; private static final int SECOND_ADDRESS_OCTET_SHIFT = 16;
private static final int FIRST_ADDRESS_OCTET_SHIFT = 24; private static final int FIRST_ADDRESS_OCTET_SHIFT = 24;
private static final int THIRD_ADDRESS_OCTET_SHIFT = 8; private static final int THIRD_ADDRESS_OCTET_SHIFT = 8;
@ -25,7 +26,7 @@ public final class SocksV4CommonUtils {
/** /**
* A constructor to stop this class being constructed. * A constructor to stop this class being constructed.
*/ */
private SocksV4CommonUtils() { private Socks4CommonUtils() {
// NOOP // NOOP
} }

View File

@ -0,0 +1,52 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.handler.codec.socksx.v4;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import io.netty.handler.codec.socksx.SocksMessage;
import io.netty.handler.codec.socksx.SocksProtocolVersion;
/**
* Encodes a {@link Socks4Request} and {@link Socks4Response} into a {@link ByteBuf}.
*/
@ChannelHandler.Sharable
public final class Socks4MessageEncoder extends MessageToByteEncoder<SocksMessage> {
public static final Socks4MessageEncoder INSTANCE = new Socks4MessageEncoder();
private Socks4MessageEncoder() { }
@Override
public boolean acceptOutboundMessage(Object msg) throws Exception {
return super.acceptOutboundMessage(msg) &&
((SocksMessage) msg).protocolVersion() == SocksProtocolVersion.SOCKS4a;
}
@Override
protected void encode(ChannelHandlerContext ctx, SocksMessage msg, ByteBuf out) throws Exception {
if (msg instanceof Socks4Response) {
((Socks4Response) msg).encodeAsByteBuf(out);
} else if (msg instanceof Socks4Request) {
((Socks4Request) msg).encodeAsByteBuf(out);
} else {
// Should not reach here.
throw new Error();
}
}
}

View File

@ -15,20 +15,26 @@
*/ */
package io.netty.handler.codec.socksx.v4; package io.netty.handler.codec.socksx.v4;
import io.netty.handler.codec.socksx.SocksMessage; import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.socksx.SocksMessageType; import io.netty.handler.codec.socks.SocksMessage;
import io.netty.handler.codec.socksx.SocksProtocolVersion; import io.netty.handler.codec.socksx.SocksProtocolVersion;
import io.netty.handler.codec.socksx.SocksRequest; import io.netty.handler.codec.socksx.SocksRequest;
/** /**
* An abstract class that defines a SocksRequest, providing common properties for * An abstract class that defines a SocksRequest, providing common properties for
* {@link SocksV4CmdRequest}. * {@link Socks4CmdRequest}.
* *
* @see SocksV4CmdRequest * @see Socks4CmdRequest
* @see UnknownSocksV4Request * @see UnknownSocks4Request
*/ */
public abstract class SocksV4Request extends SocksRequest { public abstract class Socks4Request extends SocksRequest {
protected SocksV4Request() { protected Socks4Request() {
super(SocksProtocolVersion.SOCKS4a); super(SocksProtocolVersion.SOCKS4a);
} }
/**
* We could have defined this method in {@link SocksMessage} as a protected method, but we did not,
* because we do not want to expose this method to users.
*/
abstract void encodeAsByteBuf(ByteBuf byteBuf);
} }

View File

@ -15,22 +15,27 @@
*/ */
package io.netty.handler.codec.socksx.v4; package io.netty.handler.codec.socksx.v4;
import io.netty.handler.codec.socksx.SocksMessage; import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.socksx.SocksMessageType; import io.netty.handler.codec.socks.SocksMessage;
import io.netty.handler.codec.socksx.SocksProtocolVersion; import io.netty.handler.codec.socksx.SocksProtocolVersion;
import io.netty.handler.codec.socksx.SocksResponse; import io.netty.handler.codec.socksx.SocksResponse;
import io.netty.handler.codec.socksx.v5.SocksV5ResponseType;
/** /**
* An abstract class that defines a SocksResponse, providing common properties for * An abstract class that defines a SocksResponse, providing common properties for
* {@link SocksV4CmdResponse}. * {@link Socks4CmdResponse}.
* *
* @see SocksV4CmdResponse * @see Socks4CmdResponse
* @see UnknownSocksV4Response * @see UnknownSocks4Response
*/ */
public abstract class SocksV4Response extends SocksResponse { public abstract class Socks4Response extends SocksResponse {
protected SocksV4Response() { protected Socks4Response() {
super(SocksProtocolVersion.SOCKS4a); super(SocksProtocolVersion.SOCKS4a);
} }
/**
* We could have defined this method in {@link SocksMessage} as a protected method, but we did not,
* because we do not want to expose this method to users.
*/
abstract void encodeAsByteBuf(ByteBuf byteBuf);
} }

View File

@ -20,23 +20,16 @@ import io.netty.buffer.ByteBuf;
/** /**
* An unknown socks request. * An unknown socks request.
* *
* @see SocksV4CmdRequestDecoder * @see Socks4CmdRequestDecoder
*/ */
public final class UnknownSocksV4Request extends SocksV4Request { public final class UnknownSocks4Request extends Socks4Request {
public UnknownSocksV4Request() { public static final UnknownSocks4Request INSTANCE = new UnknownSocks4Request();
}
private UnknownSocks4Request() { }
@Override @Override
public void encodeAsByteBuf(ByteBuf byteBuf) { void encodeAsByteBuf(ByteBuf byteBuf) {
// NOOP // NOOP
} }
private static class UnknownSocksV4RequestHolder {
public static final UnknownSocksV4Request HOLDER_INSTANCE = new UnknownSocksV4Request();
}
public static UnknownSocksV4Request getInstance() {
return UnknownSocksV4RequestHolder.HOLDER_INSTANCE;
}
} }

View File

@ -20,23 +20,16 @@ import io.netty.buffer.ByteBuf;
/** /**
* An unknown socks response. * An unknown socks response.
* *
* @see SocksV4CmdResponseDecoder * @see Socks4CmdResponseDecoder
*/ */
public final class UnknownSocksV4Response extends SocksV4Response { public final class UnknownSocks4Response extends Socks4Response {
public UnknownSocksV4Response() { public static final UnknownSocks4Response INSTANCE = new UnknownSocks4Response();
}
private UnknownSocks4Response() { }
@Override @Override
public void encodeAsByteBuf(ByteBuf byteBuf) { void encodeAsByteBuf(ByteBuf byteBuf) {
// NOOP // NOOP
} }
private static class UnknownSocksV4ResponseHolder {
public static final UnknownSocksV4Response HOLDER_INSTANCE = new UnknownSocksV4Response();
}
public static UnknownSocksV4Response getInstance() {
return UnknownSocksV4ResponseHolder.HOLDER_INSTANCE;
}
} }

View File

@ -15,6 +15,6 @@
*/ */
/** /**
* Encoder, decoder and their related message types for Socks. * Encoder, decoder and their related message types for SOCKSv4 protocol.
*/ */
package io.netty.handler.codec.socksx.v4; package io.netty.handler.codec.socksx.v4;

View File

@ -16,7 +16,7 @@
package io.netty.handler.codec.socksx.v5; package io.netty.handler.codec.socksx.v5;
public enum SocksV5AddressType { public enum Socks5AddressType {
IPv4((byte) 0x01), IPv4((byte) 0x01),
DOMAIN((byte) 0x03), DOMAIN((byte) 0x03),
IPv6((byte) 0x04), IPv6((byte) 0x04),
@ -24,12 +24,12 @@ public enum SocksV5AddressType {
private final byte b; private final byte b;
SocksV5AddressType(byte b) { Socks5AddressType(byte b) {
this.b = b; this.b = b;
} }
public static SocksV5AddressType valueOf(byte b) { public static Socks5AddressType valueOf(byte b) {
for (SocksV5AddressType code : values()) { for (Socks5AddressType code : values()) {
if (code.b == b) { if (code.b == b) {
return code; return code;
} }

View File

@ -23,18 +23,18 @@ import java.nio.charset.CharsetEncoder;
/** /**
* An socks auth request. * An socks auth request.
* *
* @see SocksV5AuthResponse * @see Socks5AuthResponse
* @see SocksV5AuthRequestDecoder * @see Socks5AuthRequestDecoder
*/ */
public final class SocksV5AuthRequest extends SocksV5Request { public final class Socks5AuthRequest extends Socks5Request {
private static final CharsetEncoder asciiEncoder = CharsetUtil.getEncoder(CharsetUtil.US_ASCII); private static final CharsetEncoder asciiEncoder = CharsetUtil.getEncoder(CharsetUtil.US_ASCII);
private static final SocksV5SubnegotiationVersion SUBNEGOTIATION_VERSION = private static final Socks5SubnegotiationVersion SUBNEGOTIATION_VERSION =
SocksV5SubnegotiationVersion.AUTH_PASSWORD; Socks5SubnegotiationVersion.AUTH_PASSWORD;
private final String username; private final String username;
private final String password; private final String password;
public SocksV5AuthRequest(String username, String password) { public Socks5AuthRequest(String username, String password) {
super(SocksV5RequestType.AUTH); super(Socks5RequestType.AUTH);
if (username == null) { if (username == null) {
throw new NullPointerException("username"); throw new NullPointerException("username");
} }
@ -74,7 +74,7 @@ public final class SocksV5AuthRequest extends SocksV5Request {
} }
@Override @Override
public void encodeAsByteBuf(ByteBuf byteBuf) { void encodeAsByteBuf(ByteBuf byteBuf) {
byteBuf.writeByte(SUBNEGOTIATION_VERSION.byteValue()); byteBuf.writeByte(SUBNEGOTIATION_VERSION.byteValue());
byteBuf.writeByte(username.length()); byteBuf.writeByte(username.length());
byteBuf.writeBytes(username.getBytes(CharsetUtil.US_ASCII)); byteBuf.writeBytes(username.getBytes(CharsetUtil.US_ASCII));

View File

@ -18,23 +18,23 @@ package io.netty.handler.codec.socksx.v5;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.ReplayingDecoder;
import io.netty.handler.codec.socksx.v5.SocksV5AuthRequestDecoder.State; import io.netty.handler.codec.socksx.v5.Socks5AuthRequestDecoder.State;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import java.util.List; import java.util.List;
/** /**
* Decodes {@link ByteBuf}s into {@link SocksV5AuthRequest}. * Decodes {@link ByteBuf}s into {@link Socks5AuthRequest}.
* Before returning SocksRequest decoder removes itself from pipeline. * Before returning SocksRequest decoder removes itself from pipeline.
*/ */
public class SocksV5AuthRequestDecoder extends ReplayingDecoder<State> { public class Socks5AuthRequestDecoder extends ReplayingDecoder<State> {
private SocksV5SubnegotiationVersion version; private Socks5SubnegotiationVersion version;
private int fieldLength; private int fieldLength;
private String username; private String username;
private String password; private String password;
private SocksV5Request msg = UnknownSocksV5Request.getInstance(); private Socks5Request msg = UnknownSocks5Request.INSTANCE;
public SocksV5AuthRequestDecoder() { public Socks5AuthRequestDecoder() {
super(State.CHECK_PROTOCOL_VERSION); super(State.CHECK_PROTOCOL_VERSION);
} }
@ -42,8 +42,8 @@ public class SocksV5AuthRequestDecoder extends ReplayingDecoder<State> {
protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) throws Exception {
switch (state()) { switch (state()) {
case CHECK_PROTOCOL_VERSION: { case CHECK_PROTOCOL_VERSION: {
version = SocksV5SubnegotiationVersion.valueOf(byteBuf.readByte()); version = Socks5SubnegotiationVersion.valueOf(byteBuf.readByte());
if (version != SocksV5SubnegotiationVersion.AUTH_PASSWORD) { if (version != Socks5SubnegotiationVersion.AUTH_PASSWORD) {
break; break;
} }
checkpoint(State.READ_USERNAME); checkpoint(State.READ_USERNAME);
@ -56,7 +56,7 @@ public class SocksV5AuthRequestDecoder extends ReplayingDecoder<State> {
case READ_PASSWORD: { case READ_PASSWORD: {
fieldLength = byteBuf.readByte(); fieldLength = byteBuf.readByte();
password = byteBuf.readBytes(fieldLength).toString(CharsetUtil.US_ASCII); password = byteBuf.readBytes(fieldLength).toString(CharsetUtil.US_ASCII);
msg = new SocksV5AuthRequest(username, password); msg = new Socks5AuthRequest(username, password);
} }
} }
ctx.pipeline().remove(this); ctx.pipeline().remove(this);

View File

@ -20,16 +20,16 @@ import io.netty.buffer.ByteBuf;
/** /**
* An socks auth response. * An socks auth response.
* *
* @see SocksV5AuthRequest * @see Socks5AuthRequest
* @see SocksV5AuthResponseDecoder * @see Socks5AuthResponseDecoder
*/ */
public final class SocksV5AuthResponse extends SocksV5Response { public final class Socks5AuthResponse extends Socks5Response {
private static final SocksV5SubnegotiationVersion SUBNEGOTIATION_VERSION = private static final Socks5SubnegotiationVersion SUBNEGOTIATION_VERSION =
SocksV5SubnegotiationVersion.AUTH_PASSWORD; Socks5SubnegotiationVersion.AUTH_PASSWORD;
private final SocksV5AuthStatus authStatus; private final Socks5AuthStatus authStatus;
public SocksV5AuthResponse(SocksV5AuthStatus authStatus) { public Socks5AuthResponse(Socks5AuthStatus authStatus) {
super(SocksV5ResponseType.AUTH); super(Socks5ResponseType.AUTH);
if (authStatus == null) { if (authStatus == null) {
throw new NullPointerException("authStatus"); throw new NullPointerException("authStatus");
} }
@ -37,16 +37,16 @@ public final class SocksV5AuthResponse extends SocksV5Response {
} }
/** /**
* Returns the {@link SocksV5AuthStatus} of this {@link SocksV5AuthResponse} * Returns the {@link Socks5AuthStatus} of this {@link Socks5AuthResponse}
* *
* @return The {@link SocksV5AuthStatus} of this {@link SocksV5AuthResponse} * @return The {@link Socks5AuthStatus} of this {@link Socks5AuthResponse}
*/ */
public SocksV5AuthStatus authStatus() { public Socks5AuthStatus authStatus() {
return authStatus; return authStatus;
} }
@Override @Override
public void encodeAsByteBuf(ByteBuf byteBuf) { void encodeAsByteBuf(ByteBuf byteBuf) {
byteBuf.writeByte(SUBNEGOTIATION_VERSION.byteValue()); byteBuf.writeByte(SUBNEGOTIATION_VERSION.byteValue());
byteBuf.writeByte(authStatus.byteValue()); byteBuf.writeByte(authStatus.byteValue());
} }

View File

@ -18,20 +18,20 @@ package io.netty.handler.codec.socksx.v5;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.ReplayingDecoder;
import io.netty.handler.codec.socksx.v5.SocksV5AuthResponseDecoder.State; import io.netty.handler.codec.socksx.v5.Socks5AuthResponseDecoder.State;
import java.util.List; import java.util.List;
/** /**
* Decodes {@link ByteBuf}s into {@link SocksV5AuthResponse}. * Decodes {@link ByteBuf}s into {@link Socks5AuthResponse}.
* Before returning SocksResponse decoder removes itself from pipeline. * Before returning SocksResponse decoder removes itself from pipeline.
*/ */
public class SocksV5AuthResponseDecoder extends ReplayingDecoder<State> { public class Socks5AuthResponseDecoder extends ReplayingDecoder<State> {
private SocksV5SubnegotiationVersion version; private Socks5SubnegotiationVersion version;
private SocksV5AuthStatus authStatus; private Socks5AuthStatus authStatus;
private SocksV5Response msg = UnknownSocksV5Response.getInstance(); private Socks5Response msg = UnknownSocks5Response.INSTANCE;
public SocksV5AuthResponseDecoder() { public Socks5AuthResponseDecoder() {
super(State.CHECK_PROTOCOL_VERSION); super(State.CHECK_PROTOCOL_VERSION);
} }
@ -40,15 +40,15 @@ public class SocksV5AuthResponseDecoder extends ReplayingDecoder<State> {
throws Exception { throws Exception {
switch (state()) { switch (state()) {
case CHECK_PROTOCOL_VERSION: { case CHECK_PROTOCOL_VERSION: {
version = SocksV5SubnegotiationVersion.valueOf(byteBuf.readByte()); version = Socks5SubnegotiationVersion.valueOf(byteBuf.readByte());
if (version != SocksV5SubnegotiationVersion.AUTH_PASSWORD) { if (version != Socks5SubnegotiationVersion.AUTH_PASSWORD) {
break; break;
} }
checkpoint(State.READ_AUTH_RESPONSE); checkpoint(State.READ_AUTH_RESPONSE);
} }
case READ_AUTH_RESPONSE: { case READ_AUTH_RESPONSE: {
authStatus = SocksV5AuthStatus.valueOf(byteBuf.readByte()); authStatus = Socks5AuthStatus.valueOf(byteBuf.readByte());
msg = new SocksV5AuthResponse(authStatus); msg = new Socks5AuthResponse(authStatus);
} }
} }
channelHandlerContext.pipeline().remove(this); channelHandlerContext.pipeline().remove(this);

View File

@ -16,7 +16,7 @@
package io.netty.handler.codec.socksx.v5; package io.netty.handler.codec.socksx.v5;
public enum SocksV5AuthScheme { public enum Socks5AuthScheme {
NO_AUTH((byte) 0x00), NO_AUTH((byte) 0x00),
AUTH_GSSAPI((byte) 0x01), AUTH_GSSAPI((byte) 0x01),
AUTH_PASSWORD((byte) 0x02), AUTH_PASSWORD((byte) 0x02),
@ -24,12 +24,12 @@ public enum SocksV5AuthScheme {
private final byte b; private final byte b;
SocksV5AuthScheme(byte b) { Socks5AuthScheme(byte b) {
this.b = b; this.b = b;
} }
public static SocksV5AuthScheme valueOf(byte b) { public static Socks5AuthScheme valueOf(byte b) {
for (SocksV5AuthScheme code : values()) { for (Socks5AuthScheme code : values()) {
if (code.b == b) { if (code.b == b) {
return code; return code;
} }

View File

@ -16,18 +16,18 @@
package io.netty.handler.codec.socksx.v5; package io.netty.handler.codec.socksx.v5;
public enum SocksV5AuthStatus { public enum Socks5AuthStatus {
SUCCESS((byte) 0x00), SUCCESS((byte) 0x00),
FAILURE((byte) 0xff); FAILURE((byte) 0xff);
private final byte b; private final byte b;
SocksV5AuthStatus(byte b) { Socks5AuthStatus(byte b) {
this.b = b; this.b = b;
} }
public static SocksV5AuthStatus valueOf(byte b) { public static Socks5AuthStatus valueOf(byte b) {
for (SocksV5AuthStatus code : values()) { for (Socks5AuthStatus code : values()) {
if (code.b == b) { if (code.b == b) {
return code; return code;
} }

View File

@ -24,17 +24,17 @@ import java.net.IDN;
/** /**
* An socks cmd request. * An socks cmd request.
* *
* @see SocksV5CmdResponse * @see Socks5CmdResponse
* @see SocksV5CmdRequestDecoder * @see Socks5CmdRequestDecoder
*/ */
public final class SocksV5CmdRequest extends SocksV5Request { public final class Socks5CmdRequest extends Socks5Request {
private final SocksV5CmdType cmdType; private final Socks5CmdType cmdType;
private final SocksV5AddressType addressType; private final Socks5AddressType addressType;
private final String host; private final String host;
private final int port; private final int port;
public SocksV5CmdRequest(SocksV5CmdType cmdType, SocksV5AddressType addressType, String host, int port) { public Socks5CmdRequest(Socks5CmdType cmdType, Socks5AddressType addressType, String host, int port) {
super(SocksV5RequestType.CMD); super(Socks5RequestType.CMD);
if (cmdType == null) { if (cmdType == null) {
throw new NullPointerException("cmdType"); throw new NullPointerException("cmdType");
} }
@ -73,43 +73,43 @@ public final class SocksV5CmdRequest extends SocksV5Request {
} }
/** /**
* Returns the {@link SocksV5CmdType} of this {@link SocksV5CmdRequest} * Returns the {@link Socks5CmdType} of this {@link Socks5CmdRequest}
* *
* @return The {@link SocksV5CmdType} of this {@link SocksV5CmdRequest} * @return The {@link Socks5CmdType} of this {@link Socks5CmdRequest}
*/ */
public SocksV5CmdType cmdType() { public Socks5CmdType cmdType() {
return cmdType; return cmdType;
} }
/** /**
* Returns the {@link SocksV5AddressType} of this {@link SocksV5CmdRequest} * Returns the {@link Socks5AddressType} of this {@link Socks5CmdRequest}
* *
* @return The {@link SocksV5AddressType} of this {@link SocksV5CmdRequest} * @return The {@link Socks5AddressType} of this {@link Socks5CmdRequest}
*/ */
public SocksV5AddressType addressType() { public Socks5AddressType addressType() {
return addressType; return addressType;
} }
/** /**
* Returns host that is used as a parameter in {@link SocksV5CmdType} * Returns host that is used as a parameter in {@link Socks5CmdType}
* *
* @return host that is used as a parameter in {@link SocksV5CmdType} * @return host that is used as a parameter in {@link Socks5CmdType}
*/ */
public String host() { public String host() {
return IDN.toUnicode(host); return IDN.toUnicode(host);
} }
/** /**
* Returns port that is used as a parameter in {@link SocksV5CmdType} * Returns port that is used as a parameter in {@link Socks5CmdType}
* *
* @return port that is used as a parameter in {@link SocksV5CmdType} * @return port that is used as a parameter in {@link Socks5CmdType}
*/ */
public int port() { public int port() {
return port; return port;
} }
@Override @Override
public void encodeAsByteBuf(ByteBuf byteBuf) { void encodeAsByteBuf(ByteBuf byteBuf) {
byteBuf.writeByte(protocolVersion().byteValue()); byteBuf.writeByte(protocolVersion().byteValue());
byteBuf.writeByte(cmdType.byteValue()); byteBuf.writeByte(cmdType.byteValue());
byteBuf.writeByte(0x00); byteBuf.writeByte(0x00);

View File

@ -19,27 +19,27 @@ import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.ReplayingDecoder;
import io.netty.handler.codec.socksx.SocksProtocolVersion; import io.netty.handler.codec.socksx.SocksProtocolVersion;
import io.netty.handler.codec.socksx.v5.SocksV5CmdRequestDecoder.State; import io.netty.handler.codec.socksx.v5.Socks5CmdRequestDecoder.State;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import java.util.List; import java.util.List;
/** /**
* Decodes {@link ByteBuf}s into {@link SocksV5CmdRequest}. * Decodes {@link ByteBuf}s into {@link Socks5CmdRequest}.
* Before returning SocksRequest decoder removes itself from pipeline. * Before returning SocksRequest decoder removes itself from pipeline.
*/ */
public class SocksV5CmdRequestDecoder extends ReplayingDecoder<State> { public class Socks5CmdRequestDecoder extends ReplayingDecoder<State> {
private SocksProtocolVersion version; private SocksProtocolVersion version;
private int fieldLength; private int fieldLength;
private SocksV5CmdType cmdType; private Socks5CmdType cmdType;
private SocksV5AddressType addressType; private Socks5AddressType addressType;
@SuppressWarnings("UnusedDeclaration") @SuppressWarnings("UnusedDeclaration")
private byte reserved; private byte reserved;
private String host; private String host;
private int port; private int port;
private SocksV5Request msg = UnknownSocksV5Request.getInstance(); private Socks5Request msg = UnknownSocks5Request.INSTANCE;
public SocksV5CmdRequestDecoder() { public Socks5CmdRequestDecoder() {
super(State.CHECK_PROTOCOL_VERSION); super(State.CHECK_PROTOCOL_VERSION);
} }
@ -54,30 +54,30 @@ public class SocksV5CmdRequestDecoder extends ReplayingDecoder<State> {
checkpoint(State.READ_CMD_HEADER); checkpoint(State.READ_CMD_HEADER);
} }
case READ_CMD_HEADER: { case READ_CMD_HEADER: {
cmdType = SocksV5CmdType.valueOf(byteBuf.readByte()); cmdType = Socks5CmdType.valueOf(byteBuf.readByte());
reserved = byteBuf.readByte(); reserved = byteBuf.readByte();
addressType = SocksV5AddressType.valueOf(byteBuf.readByte()); addressType = Socks5AddressType.valueOf(byteBuf.readByte());
checkpoint(State.READ_CMD_ADDRESS); checkpoint(State.READ_CMD_ADDRESS);
} }
case READ_CMD_ADDRESS: { case READ_CMD_ADDRESS: {
switch (addressType) { switch (addressType) {
case IPv4: { case IPv4: {
host = SocksV5CommonUtils.intToIp(byteBuf.readInt()); host = Socks5CommonUtils.intToIp(byteBuf.readInt());
port = byteBuf.readUnsignedShort(); port = byteBuf.readUnsignedShort();
msg = new SocksV5CmdRequest(cmdType, addressType, host, port); msg = new Socks5CmdRequest(cmdType, addressType, host, port);
break; break;
} }
case DOMAIN: { case DOMAIN: {
fieldLength = byteBuf.readByte(); fieldLength = byteBuf.readByte();
host = byteBuf.readBytes(fieldLength).toString(CharsetUtil.US_ASCII); host = byteBuf.readBytes(fieldLength).toString(CharsetUtil.US_ASCII);
port = byteBuf.readUnsignedShort(); port = byteBuf.readUnsignedShort();
msg = new SocksV5CmdRequest(cmdType, addressType, host, port); msg = new Socks5CmdRequest(cmdType, addressType, host, port);
break; break;
} }
case IPv6: { case IPv6: {
host = SocksV5CommonUtils.ipv6toStr(byteBuf.readBytes(16).array()); host = Socks5CommonUtils.ipv6toStr(byteBuf.readBytes(16).array());
port = byteBuf.readUnsignedShort(); port = byteBuf.readUnsignedShort();
msg = new SocksV5CmdRequest(cmdType, addressType, host, port); msg = new Socks5CmdRequest(cmdType, addressType, host, port);
break; break;
} }
case UNKNOWN: case UNKNOWN:

View File

@ -24,13 +24,13 @@ import java.net.IDN;
/** /**
* A socks cmd response. * A socks cmd response.
* *
* @see SocksV5CmdRequest * @see Socks5CmdRequest
* @see SocksV5CmdResponseDecoder * @see Socks5CmdResponseDecoder
*/ */
public final class SocksV5CmdResponse extends SocksV5Response { public final class Socks5CmdResponse extends Socks5Response {
private final SocksV5CmdStatus cmdStatus; private final Socks5CmdStatus cmdStatus;
private final SocksV5AddressType addressType; private final Socks5AddressType addressType;
private final String host; private final String host;
private final int port; private final int port;
@ -42,7 +42,7 @@ public final class SocksV5CmdResponse extends SocksV5Response {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00}; 0x00, 0x00, 0x00, 0x00};
public SocksV5CmdResponse(SocksV5CmdStatus cmdStatus, SocksV5AddressType addressType) { public Socks5CmdResponse(Socks5CmdStatus cmdStatus, Socks5AddressType addressType) {
this(cmdStatus, addressType, null, 0); this(cmdStatus, addressType, null, 0);
} }
@ -59,8 +59,8 @@ public final class SocksV5CmdResponse extends SocksV5Response {
* @throws IllegalArgumentException in case host or port cannot be validated * @throws IllegalArgumentException in case host or port cannot be validated
* @see IDN#toASCII(String) * @see IDN#toASCII(String)
*/ */
public SocksV5CmdResponse(SocksV5CmdStatus cmdStatus, SocksV5AddressType addressType, String host, int port) { public Socks5CmdResponse(Socks5CmdStatus cmdStatus, Socks5AddressType addressType, String host, int port) {
super(SocksV5ResponseType.CMD); super(Socks5ResponseType.CMD);
if (cmdStatus == null) { if (cmdStatus == null) {
throw new NullPointerException("cmdStatus"); throw new NullPointerException("cmdStatus");
} }
@ -100,29 +100,29 @@ public final class SocksV5CmdResponse extends SocksV5Response {
} }
/** /**
* Returns the {@link SocksV5CmdStatus} of this {@link SocksV5CmdResponse} * Returns the {@link Socks5CmdStatus} of this {@link Socks5CmdResponse}
* *
* @return The {@link SocksV5CmdStatus} of this {@link SocksV5CmdResponse} * @return The {@link Socks5CmdStatus} of this {@link Socks5CmdResponse}
*/ */
public SocksV5CmdStatus cmdStatus() { public Socks5CmdStatus cmdStatus() {
return cmdStatus; return cmdStatus;
} }
/** /**
* Returns the {@link SocksV5AddressType} of this {@link SocksV5CmdResponse} * Returns the {@link Socks5AddressType} of this {@link Socks5CmdResponse}
* *
* @return The {@link SocksV5AddressType} of this {@link SocksV5CmdResponse} * @return The {@link Socks5AddressType} of this {@link Socks5CmdResponse}
*/ */
public SocksV5AddressType addressType() { public Socks5AddressType addressType() {
return addressType; return addressType;
} }
/** /**
* Returns host that is used as a parameter in {@link SocksV5CmdType}. * Returns host that is used as a parameter in {@link Socks5CmdType}.
* Host (BND.ADDR field in response) is address that server used when connecting to the target host. * Host (BND.ADDR field in response) is address that server used when connecting to the target host.
* This is typically different from address which client uses to connect to the SOCKS server. * This is typically different from address which client uses to connect to the SOCKS server.
* *
* @return host that is used as a parameter in {@link SocksV5CmdType} * @return host that is used as a parameter in {@link Socks5CmdType}
* or null when there was no host specified during response construction * or null when there was no host specified during response construction
*/ */
public String host() { public String host() {
@ -134,17 +134,17 @@ public final class SocksV5CmdResponse extends SocksV5Response {
} }
/** /**
* Returns port that is used as a parameter in {@link SocksV5CmdType}. * Returns port that is used as a parameter in {@link Socks5CmdType}.
* Port (BND.PORT field in response) is port that the server assigned to connect to the target host. * Port (BND.PORT field in response) is port that the server assigned to connect to the target host.
* *
* @return port that is used as a parameter in {@link SocksV5CmdType} * @return port that is used as a parameter in {@link Socks5CmdType}
*/ */
public int port() { public int port() {
return port; return port;
} }
@Override @Override
public void encodeAsByteBuf(ByteBuf byteBuf) { void encodeAsByteBuf(ByteBuf byteBuf) {
byteBuf.writeByte(protocolVersion().byteValue()); byteBuf.writeByte(protocolVersion().byteValue());
byteBuf.writeByte(cmdStatus.byteValue()); byteBuf.writeByte(cmdStatus.byteValue());
byteBuf.writeByte(0x00); byteBuf.writeByte(0x00);

View File

@ -19,26 +19,25 @@ import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.ReplayingDecoder;
import io.netty.handler.codec.socksx.SocksProtocolVersion; import io.netty.handler.codec.socksx.SocksProtocolVersion;
import io.netty.handler.codec.socksx.v5.SocksV5CmdResponseDecoder.State; import io.netty.handler.codec.socksx.v5.Socks5CmdResponseDecoder.State;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import java.util.List; import java.util.List;
/** /**
* Decodes {@link ByteBuf}s into {@link SocksV5CmdResponse}. * Decodes {@link ByteBuf}s into {@link Socks5CmdResponse}.
* Before returning SocksResponse decoder removes itself from pipeline. * Before returning SocksResponse decoder removes itself from pipeline.
*/ */
public class SocksV5CmdResponseDecoder extends ReplayingDecoder<State> { public class Socks5CmdResponseDecoder extends ReplayingDecoder<State> {
private SocksProtocolVersion version; private SocksProtocolVersion version;
private int fieldLength; private int fieldLength;
private SocksV5CmdStatus cmdStatus; private Socks5CmdStatus cmdStatus;
private SocksV5AddressType addressType; private Socks5AddressType addressType;
private byte reserved;
private String host; private String host;
private int port; private int port;
private SocksV5Response msg = UnknownSocksV5Response.getInstance(); private Socks5Response msg = UnknownSocks5Response.INSTANCE;
public SocksV5CmdResponseDecoder() { public Socks5CmdResponseDecoder() {
super(State.CHECK_PROTOCOL_VERSION); super(State.CHECK_PROTOCOL_VERSION);
} }
@ -53,30 +52,30 @@ public class SocksV5CmdResponseDecoder extends ReplayingDecoder<State> {
checkpoint(State.READ_CMD_HEADER); checkpoint(State.READ_CMD_HEADER);
} }
case READ_CMD_HEADER: { case READ_CMD_HEADER: {
cmdStatus = SocksV5CmdStatus.valueOf(byteBuf.readByte()); cmdStatus = Socks5CmdStatus.valueOf(byteBuf.readByte());
reserved = byteBuf.readByte(); byteBuf.skipBytes(1); // reserved
addressType = SocksV5AddressType.valueOf(byteBuf.readByte()); addressType = Socks5AddressType.valueOf(byteBuf.readByte());
checkpoint(State.READ_CMD_ADDRESS); checkpoint(State.READ_CMD_ADDRESS);
} }
case READ_CMD_ADDRESS: { case READ_CMD_ADDRESS: {
switch (addressType) { switch (addressType) {
case IPv4: { case IPv4: {
host = SocksV5CommonUtils.intToIp(byteBuf.readInt()); host = Socks5CommonUtils.intToIp(byteBuf.readInt());
port = byteBuf.readUnsignedShort(); port = byteBuf.readUnsignedShort();
msg = new SocksV5CmdResponse(cmdStatus, addressType, host, port); msg = new Socks5CmdResponse(cmdStatus, addressType, host, port);
break; break;
} }
case DOMAIN: { case DOMAIN: {
fieldLength = byteBuf.readByte(); fieldLength = byteBuf.readByte();
host = byteBuf.readBytes(fieldLength).toString(CharsetUtil.US_ASCII); host = byteBuf.readBytes(fieldLength).toString(CharsetUtil.US_ASCII);
port = byteBuf.readUnsignedShort(); port = byteBuf.readUnsignedShort();
msg = new SocksV5CmdResponse(cmdStatus, addressType, host, port); msg = new Socks5CmdResponse(cmdStatus, addressType, host, port);
break; break;
} }
case IPv6: { case IPv6: {
host = SocksV5CommonUtils.ipv6toStr(byteBuf.readBytes(16).array()); host = Socks5CommonUtils.ipv6toStr(byteBuf.readBytes(16).array());
port = byteBuf.readUnsignedShort(); port = byteBuf.readUnsignedShort();
msg = new SocksV5CmdResponse(cmdStatus, addressType, host, port); msg = new Socks5CmdResponse(cmdStatus, addressType, host, port);
break; break;
} }
case UNKNOWN: case UNKNOWN:

View File

@ -16,7 +16,7 @@
package io.netty.handler.codec.socksx.v5; package io.netty.handler.codec.socksx.v5;
public enum SocksV5CmdStatus { public enum Socks5CmdStatus {
SUCCESS((byte) 0x00), SUCCESS((byte) 0x00),
FAILURE((byte) 0x01), FAILURE((byte) 0x01),
FORBIDDEN((byte) 0x02), FORBIDDEN((byte) 0x02),
@ -30,12 +30,12 @@ public enum SocksV5CmdStatus {
private final byte b; private final byte b;
SocksV5CmdStatus(byte b) { Socks5CmdStatus(byte b) {
this.b = b; this.b = b;
} }
public static SocksV5CmdStatus valueOf(byte b) { public static Socks5CmdStatus valueOf(byte b) {
for (SocksV5CmdStatus code : values()) { for (Socks5CmdStatus code : values()) {
if (code.b == b) { if (code.b == b) {
return code; return code;
} }

View File

@ -16,7 +16,7 @@
package io.netty.handler.codec.socksx.v5; package io.netty.handler.codec.socksx.v5;
public enum SocksV5CmdType { public enum Socks5CmdType {
CONNECT((byte) 0x01), CONNECT((byte) 0x01),
BIND((byte) 0x02), BIND((byte) 0x02),
UDP((byte) 0x03), UDP((byte) 0x03),
@ -24,12 +24,12 @@ public enum SocksV5CmdType {
private final byte b; private final byte b;
SocksV5CmdType(byte b) { Socks5CmdType(byte b) {
this.b = b; this.b = b;
} }
public static SocksV5CmdType valueOf(byte b) { public static Socks5CmdType valueOf(byte b) {
for (SocksV5CmdType code : values()) { for (Socks5CmdType code : values()) {
if (code.b == b) { if (code.b == b) {
return code; return code;
} }

View File

@ -16,7 +16,8 @@
package io.netty.handler.codec.socksx.v5; package io.netty.handler.codec.socksx.v5;
import io.netty.util.internal.StringUtil; import io.netty.util.internal.StringUtil;
public final class SocksV5CommonUtils { final class Socks5CommonUtils {
private static final int SECOND_ADDRESS_OCTET_SHIFT = 16; private static final int SECOND_ADDRESS_OCTET_SHIFT = 16;
private static final int FIRST_ADDRESS_OCTET_SHIFT = 24; private static final int FIRST_ADDRESS_OCTET_SHIFT = 24;
private static final int THIRD_ADDRESS_OCTET_SHIFT = 8; private static final int THIRD_ADDRESS_OCTET_SHIFT = 8;
@ -25,7 +26,7 @@ public final class SocksV5CommonUtils {
/** /**
* A constructor to stop this class being constructed. * A constructor to stop this class being constructed.
*/ */
private SocksV5CommonUtils() { private Socks5CommonUtils() {
// NOOP // NOOP
} }

View File

@ -23,14 +23,14 @@ import java.util.List;
/** /**
* An socks init request. * An socks init request.
* *
* @see SocksV5InitResponse * @see Socks5InitResponse
* @see SocksV5InitRequestDecoder * @see Socks5InitRequestDecoder
*/ */
public final class SocksV5InitRequest extends SocksV5Request { public final class Socks5InitRequest extends Socks5Request {
private final List<SocksV5AuthScheme> authSchemes; private final List<Socks5AuthScheme> authSchemes;
public SocksV5InitRequest(List<SocksV5AuthScheme> authSchemes) { public Socks5InitRequest(List<Socks5AuthScheme> authSchemes) {
super(SocksV5RequestType.INIT); super(Socks5RequestType.INIT);
if (authSchemes == null) { if (authSchemes == null) {
throw new NullPointerException("authSchemes"); throw new NullPointerException("authSchemes");
} }
@ -38,19 +38,19 @@ public final class SocksV5InitRequest extends SocksV5Request {
} }
/** /**
* Returns the List<{@link SocksV5AuthScheme}> of this {@link SocksV5InitRequest} * Returns the List<{@link Socks5AuthScheme}> of this {@link Socks5InitRequest}
* *
* @return The List<{@link SocksV5AuthScheme}> of this {@link SocksV5InitRequest} * @return The List<{@link Socks5AuthScheme}> of this {@link Socks5InitRequest}
*/ */
public List<SocksV5AuthScheme> authSchemes() { public List<Socks5AuthScheme> authSchemes() {
return Collections.unmodifiableList(authSchemes); return Collections.unmodifiableList(authSchemes);
} }
@Override @Override
public void encodeAsByteBuf(ByteBuf byteBuf) { void encodeAsByteBuf(ByteBuf byteBuf) {
byteBuf.writeByte(protocolVersion().byteValue()); byteBuf.writeByte(protocolVersion().byteValue());
byteBuf.writeByte(authSchemes.size()); byteBuf.writeByte(authSchemes.size());
for (SocksV5AuthScheme authScheme : authSchemes) { for (Socks5AuthScheme authScheme : authSchemes) {
byteBuf.writeByte(authScheme.byteValue()); byteBuf.writeByte(authScheme.byteValue());
} }
} }

View File

@ -19,22 +19,22 @@ import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.ReplayingDecoder;
import io.netty.handler.codec.socksx.SocksProtocolVersion; import io.netty.handler.codec.socksx.SocksProtocolVersion;
import io.netty.handler.codec.socksx.v5.SocksV5InitRequestDecoder.State; import io.netty.handler.codec.socksx.v5.Socks5InitRequestDecoder.State;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* Decodes {@link ByteBuf}s into {@link SocksV5InitRequest}. * Decodes {@link ByteBuf}s into {@link Socks5InitRequest}.
* Before returning SocksRequest decoder removes itself from pipeline. * Before returning SocksRequest decoder removes itself from pipeline.
*/ */
public class SocksV5InitRequestDecoder extends ReplayingDecoder<State> { public class Socks5InitRequestDecoder extends ReplayingDecoder<State> {
private final List<SocksV5AuthScheme> authSchemes = new ArrayList<SocksV5AuthScheme>(); private final List<Socks5AuthScheme> authSchemes = new ArrayList<Socks5AuthScheme>();
private SocksProtocolVersion version; private SocksProtocolVersion version;
private byte authSchemeNum; private byte authSchemeNum;
private SocksV5Request msg = UnknownSocksV5Request.getInstance(); private Socks5Request msg = UnknownSocks5Request.INSTANCE;
public SocksV5InitRequestDecoder() { public Socks5InitRequestDecoder() {
super(State.CHECK_PROTOCOL_VERSION); super(State.CHECK_PROTOCOL_VERSION);
} }
@ -52,9 +52,9 @@ public class SocksV5InitRequestDecoder extends ReplayingDecoder<State> {
authSchemes.clear(); authSchemes.clear();
authSchemeNum = byteBuf.readByte(); authSchemeNum = byteBuf.readByte();
for (int i = 0; i < authSchemeNum; i++) { for (int i = 0; i < authSchemeNum; i++) {
authSchemes.add(SocksV5AuthScheme.valueOf(byteBuf.readByte())); authSchemes.add(Socks5AuthScheme.valueOf(byteBuf.readByte()));
} }
msg = new SocksV5InitRequest(authSchemes); msg = new Socks5InitRequest(authSchemes);
break; break;
} }
} }

View File

@ -20,14 +20,14 @@ import io.netty.buffer.ByteBuf;
/** /**
* An socks init response. * An socks init response.
* *
* @see SocksV5InitRequest * @see Socks5InitRequest
* @see SocksV5InitResponseDecoder * @see Socks5InitResponseDecoder
*/ */
public final class SocksV5InitResponse extends SocksV5Response { public final class Socks5InitResponse extends Socks5Response {
private final SocksV5AuthScheme authScheme; private final Socks5AuthScheme authScheme;
public SocksV5InitResponse(SocksV5AuthScheme authScheme) { public Socks5InitResponse(Socks5AuthScheme authScheme) {
super(SocksV5ResponseType.INIT); super(Socks5ResponseType.INIT);
if (authScheme == null) { if (authScheme == null) {
throw new NullPointerException("authScheme"); throw new NullPointerException("authScheme");
} }
@ -35,16 +35,16 @@ public final class SocksV5InitResponse extends SocksV5Response {
} }
/** /**
* Returns the {@link SocksV5AuthScheme} of this {@link SocksV5InitResponse} * Returns the {@link Socks5AuthScheme} of this {@link Socks5InitResponse}
* *
* @return The {@link SocksV5AuthScheme} of this {@link SocksV5InitResponse} * @return The {@link Socks5AuthScheme} of this {@link Socks5InitResponse}
*/ */
public SocksV5AuthScheme authScheme() { public Socks5AuthScheme authScheme() {
return authScheme; return authScheme;
} }
@Override @Override
public void encodeAsByteBuf(ByteBuf byteBuf) { void encodeAsByteBuf(ByteBuf byteBuf) {
byteBuf.writeByte(protocolVersion().byteValue()); byteBuf.writeByte(protocolVersion().byteValue());
byteBuf.writeByte(authScheme.byteValue()); byteBuf.writeByte(authScheme.byteValue());
} }

View File

@ -19,21 +19,21 @@ import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.ReplayingDecoder;
import io.netty.handler.codec.socksx.SocksProtocolVersion; import io.netty.handler.codec.socksx.SocksProtocolVersion;
import io.netty.handler.codec.socksx.v5.SocksV5InitResponseDecoder.State; import io.netty.handler.codec.socksx.v5.Socks5InitResponseDecoder.State;
import java.util.List; import java.util.List;
/** /**
* Decodes {@link ByteBuf}s into {@link SocksV5InitResponse}. * Decodes {@link ByteBuf}s into {@link Socks5InitResponse}.
* Before returning SocksResponse decoder removes itself from pipeline. * Before returning SocksResponse decoder removes itself from pipeline.
*/ */
public class SocksV5InitResponseDecoder extends ReplayingDecoder<State> { public class Socks5InitResponseDecoder extends ReplayingDecoder<State> {
private SocksProtocolVersion version; private SocksProtocolVersion version;
private SocksV5AuthScheme authScheme; private Socks5AuthScheme authScheme;
private SocksV5Response msg = UnknownSocksV5Response.getInstance(); private Socks5Response msg = UnknownSocks5Response.INSTANCE;
public SocksV5InitResponseDecoder() { public Socks5InitResponseDecoder() {
super(State.CHECK_PROTOCOL_VERSION); super(State.CHECK_PROTOCOL_VERSION);
} }
@ -48,8 +48,8 @@ public class SocksV5InitResponseDecoder extends ReplayingDecoder<State> {
checkpoint(State.READ_PREFFERED_AUTH_TYPE); checkpoint(State.READ_PREFFERED_AUTH_TYPE);
} }
case READ_PREFFERED_AUTH_TYPE: { case READ_PREFFERED_AUTH_TYPE: {
authScheme = SocksV5AuthScheme.valueOf(byteBuf.readByte()); authScheme = Socks5AuthScheme.valueOf(byteBuf.readByte());
msg = new SocksV5InitResponse(authScheme); msg = new Socks5InitResponse(authScheme);
break; break;
} }
} }

View File

@ -13,40 +13,40 @@
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package io.netty.handler.codec.socksx; package io.netty.handler.codec.socksx.v5;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder; import io.netty.handler.codec.MessageToByteEncoder;
import io.netty.handler.codec.socksx.SocksMessage;
import io.netty.handler.codec.socksx.SocksProtocolVersion;
/** /**
* Encodes an {@link SocksMessage} into a {@link ByteBuf}. * Encodes a {@link Socks5Request} and {@link Socks5Response} into a {@link ByteBuf}.
* {@link MessageToByteEncoder} implementation.
* Use this with {@link SocksV4CmdRequest},
* {@link SocksV4CmdRequest},
* {@link SocksV5InitRequest},
* {@link SocksV5InitResponse},
* {@link SocksV5AuthRequest},
* {@link SocksV5AuthResponse},
* {@link SocksV5CmdRequest} and
* {@link SocksV5CmdResponse}
*/ */
@ChannelHandler.Sharable @ChannelHandler.Sharable
public class SocksMessageEncoder extends MessageToByteEncoder<SocksMessage> { public final class Socks5MessageEncoder extends MessageToByteEncoder<SocksMessage> {
private static final String name = "SOCKS_MESSAGE_ENCODER";
public static final Socks5MessageEncoder INSTANCE = new Socks5MessageEncoder();
private Socks5MessageEncoder() { }
@Override
public boolean acceptOutboundMessage(Object msg) throws Exception {
return super.acceptOutboundMessage(msg) &&
((SocksMessage) msg).protocolVersion() == SocksProtocolVersion.SOCKS5;
}
@Override @Override
@SuppressWarnings("deprecation")
protected void encode(ChannelHandlerContext ctx, SocksMessage msg, ByteBuf out) throws Exception { protected void encode(ChannelHandlerContext ctx, SocksMessage msg, ByteBuf out) throws Exception {
msg.encodeAsByteBuf(out); if (msg instanceof Socks5Response) {
} ((Socks5Response) msg).encodeAsByteBuf(out);
} else if (msg instanceof Socks5Request) {
private static class SocksMessageEncoderHolder { ((Socks5Request) msg).encodeAsByteBuf(out);
public static final SocksMessageEncoder HOLDER_INSTANCE = new SocksMessageEncoder(); } else {
} // Should not reach here.
throw new Error();
public static SocksMessageEncoder getInstance() { }
return SocksMessageEncoderHolder.HOLDER_INSTANCE;
} }
} }

View File

@ -15,27 +15,27 @@
*/ */
package io.netty.handler.codec.socksx.v5; package io.netty.handler.codec.socksx.v5;
import io.netty.handler.codec.socksx.SocksMessage; import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.socksx.SocksMessageType; import io.netty.handler.codec.socks.SocksMessage;
import io.netty.handler.codec.socksx.SocksProtocolVersion; import io.netty.handler.codec.socksx.SocksProtocolVersion;
import io.netty.handler.codec.socksx.SocksRequest; import io.netty.handler.codec.socksx.SocksRequest;
/** /**
* An abstract class that defines a SocksRequest, providing common properties for * An abstract class that defines a SocksRequest, providing common properties for
* {@link SocksV5InitRequest}, * {@link Socks5InitRequest},
* {@link SocksV5AuthRequest}, * {@link Socks5AuthRequest},
* {@link SocksV5CmdRequest} and * {@link Socks5CmdRequest} and
* {@link UnknownSocksV5Request}. * {@link UnknownSocks5Request}.
* *
* @see SocksV5InitRequest * @see Socks5InitRequest
* @see SocksV5AuthRequest * @see Socks5AuthRequest
* @see SocksV5CmdRequest * @see Socks5CmdRequest
* @see UnknownSocksV5Request * @see UnknownSocks5Request
*/ */
public abstract class SocksV5Request extends SocksRequest { public abstract class Socks5Request extends SocksRequest {
private final SocksV5RequestType requestType; private final Socks5RequestType requestType;
protected SocksV5Request(SocksV5RequestType requestType) { protected Socks5Request(Socks5RequestType requestType) {
super(SocksProtocolVersion.SOCKS5); super(SocksProtocolVersion.SOCKS5);
if (requestType == null) { if (requestType == null) {
throw new NullPointerException("requestType"); throw new NullPointerException("requestType");
@ -48,7 +48,13 @@ public abstract class SocksV5Request extends SocksRequest {
* *
* @return socks request type * @return socks request type
*/ */
public SocksV5RequestType requestType() { public Socks5RequestType requestType() {
return requestType; return requestType;
} }
/**
* We could have defined this method in {@link SocksMessage} as a protected method, but we did not,
* because we do not want to expose this method to users.
*/
abstract void encodeAsByteBuf(ByteBuf byteBuf);
} }

View File

@ -19,7 +19,7 @@ package io.netty.handler.codec.socksx.v5;
/** /**
* Type of socks request * Type of socks request
*/ */
public enum SocksV5RequestType { public enum Socks5RequestType {
INIT, INIT,
AUTH, AUTH,
CMD, CMD,

View File

@ -15,27 +15,27 @@
*/ */
package io.netty.handler.codec.socksx.v5; package io.netty.handler.codec.socksx.v5;
import io.netty.handler.codec.socksx.SocksMessage; import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.socksx.SocksMessageType; import io.netty.handler.codec.socks.SocksMessage;
import io.netty.handler.codec.socksx.SocksProtocolVersion; import io.netty.handler.codec.socksx.SocksProtocolVersion;
import io.netty.handler.codec.socksx.SocksResponse; import io.netty.handler.codec.socksx.SocksResponse;
/** /**
* An abstract class that defines a SocksResponse, providing common properties for * An abstract class that defines a SocksResponse, providing common properties for
* {@link SocksV5InitResponse}, * {@link Socks5InitResponse},
* {@link SocksV5AuthResponse}, * {@link Socks5AuthResponse},
* {@link SocksV5CmdResponse} * {@link Socks5CmdResponse}
* and {@link UnknownSocksV5Response}. * and {@link UnknownSocks5Response}.
* *
* @see SocksV5InitResponse * @see Socks5InitResponse
* @see SocksV5AuthResponse * @see Socks5AuthResponse
* @see SocksV5CmdResponse * @see Socks5CmdResponse
* @see UnknownSocksV5Response * @see UnknownSocks5Response
*/ */
public abstract class SocksV5Response extends SocksResponse { public abstract class Socks5Response extends SocksResponse {
private final SocksV5ResponseType responseType; private final Socks5ResponseType responseType;
protected SocksV5Response(SocksV5ResponseType responseType) { protected Socks5Response(Socks5ResponseType responseType) {
super(SocksProtocolVersion.SOCKS5); super(SocksProtocolVersion.SOCKS5);
if (responseType == null) { if (responseType == null) {
throw new NullPointerException("responseType"); throw new NullPointerException("responseType");
@ -48,7 +48,13 @@ public abstract class SocksV5Response extends SocksResponse {
* *
* @return socks response type * @return socks response type
*/ */
public SocksV5ResponseType responseType() { public Socks5ResponseType responseType() {
return responseType; return responseType;
} }
/**
* We could have defined this method in {@link SocksMessage} as a protected method, but we did not,
* because we do not want to expose this method to users.
*/
abstract void encodeAsByteBuf(ByteBuf byteBuf);
} }

View File

@ -19,7 +19,7 @@ package io.netty.handler.codec.socksx.v5;
/** /**
* Type of socks response * Type of socks response
*/ */
public enum SocksV5ResponseType { public enum Socks5ResponseType {
INIT, INIT,
AUTH, AUTH,
CMD, CMD,

View File

@ -16,18 +16,18 @@
package io.netty.handler.codec.socksx.v5; package io.netty.handler.codec.socksx.v5;
public enum SocksV5SubnegotiationVersion { public enum Socks5SubnegotiationVersion {
AUTH_PASSWORD((byte) 0x01), AUTH_PASSWORD((byte) 0x01),
UNKNOWN((byte) 0xff); UNKNOWN((byte) 0xff);
private final byte b; private final byte b;
SocksV5SubnegotiationVersion(byte b) { Socks5SubnegotiationVersion(byte b) {
this.b = b; this.b = b;
} }
public static SocksV5SubnegotiationVersion valueOf(byte b) { public static Socks5SubnegotiationVersion valueOf(byte b) {
for (SocksV5SubnegotiationVersion code : values()) { for (Socks5SubnegotiationVersion code : values()) {
if (code.b == b) { if (code.b == b) {
return code; return code;
} }

View File

@ -0,0 +1,39 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.handler.codec.socksx.v5;
import io.netty.buffer.ByteBuf;
/**
* An unknown socks request.
*
* @see Socks5InitRequestDecoder
* @see Socks5AuthRequestDecoder
* @see Socks5CmdRequestDecoder
*/
public final class UnknownSocks5Request extends Socks5Request {
public static final UnknownSocks5Request INSTANCE = new UnknownSocks5Request();
private UnknownSocks5Request() {
super(Socks5RequestType.UNKNOWN);
}
@Override
void encodeAsByteBuf(ByteBuf byteBuf) {
// NOOP
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.handler.codec.socksx.v5;
import io.netty.buffer.ByteBuf;
/**
* An unknown socks response.
*
* @see Socks5InitResponseDecoder
* @see Socks5AuthResponseDecoder
* @see Socks5CmdResponseDecoder
*/
public final class UnknownSocks5Response extends Socks5Response {
public static final UnknownSocks5Response INSTANCE = new UnknownSocks5Response();
private UnknownSocks5Response() {
super(Socks5ResponseType.UNKNOWN);
}
@Override
void encodeAsByteBuf(ByteBuf byteBuf) {
// NOOP
}
}

View File

@ -1,45 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.handler.codec.socksx.v5;
import io.netty.buffer.ByteBuf;
/**
* An unknown socks request.
*
* @see SocksV5InitRequestDecoder
* @see SocksV5AuthRequestDecoder
* @see SocksV5CmdRequestDecoder
*/
public final class UnknownSocksV5Request extends SocksV5Request {
public UnknownSocksV5Request() {
super(SocksV5RequestType.UNKNOWN);
}
@Override
public void encodeAsByteBuf(ByteBuf byteBuf) {
// NOOP
}
private static class UnknownSocksV5RequestHolder {
public static final UnknownSocksV5Request HOLDER_INSTANCE = new UnknownSocksV5Request();
}
public static UnknownSocksV5Request getInstance() {
return UnknownSocksV5RequestHolder.HOLDER_INSTANCE;
}
}

View File

@ -1,45 +0,0 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.handler.codec.socksx.v5;
import io.netty.buffer.ByteBuf;
/**
* An unknown socks response.
*
* @see SocksV5InitResponseDecoder
* @see SocksV5AuthResponseDecoder
* @see SocksV5CmdResponseDecoder
*/
public final class UnknownSocksV5Response extends SocksV5Response {
public UnknownSocksV5Response() {
super(SocksV5ResponseType.UNKNOWN);
}
@Override
public void encodeAsByteBuf(ByteBuf byteBuf) {
// NOOP
}
private static class UnknownSocksV5ResponseHolder {
public static final UnknownSocksV5Response HOLDER_INSTANCE = new UnknownSocksV5Response();
}
public static UnknownSocksV5Response getInstance() {
return UnknownSocksV5ResponseHolder.HOLDER_INSTANCE;
}
}

View File

@ -15,7 +15,6 @@
*/ */
/** /**
* Encoder, decoder and their related message types for Socks. * Encoder, decoder and their related message types for SOCKSv5 protocol.
*/ */
package io.netty.handler.codec.socksx.v5; package io.netty.handler.codec.socksx.v5;
// TODO: Combine decoders into one.

View File

@ -16,35 +16,27 @@
package io.netty.handler.codec.socksx.v4; package io.netty.handler.codec.socksx.v4;
import io.netty.channel.embedded.EmbeddedChannel; import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.socksx.v5.SocksV5AddressType;
import io.netty.handler.codec.socksx.v5.SocksV5CmdRequest;
import io.netty.handler.codec.socksx.v5.SocksV5CmdType;
import io.netty.handler.codec.socksx.v5.UnknownSocksV5Request;
import io.netty.util.internal.SystemPropertyUtil;
import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory; import io.netty.util.internal.logging.InternalLoggerFactory;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
public class SocksV4CmdRequestDecoderTest { public class Socks4CmdRequestDecoderTest {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(SocksV4CmdRequestDecoderTest.class); private static final InternalLogger logger = InternalLoggerFactory.getInstance(Socks4CmdRequestDecoderTest.class);
private static void testSocksV4CmdRequestDecoderWithDifferentParams(String userId, private static void testSocksV4CmdRequestDecoderWithDifferentParams(String userId,
SocksV4CmdType cmdType, Socks4CmdType cmdType,
String host, String host,
int port) { int port) {
logger.debug("Testing cmdType: " + cmdType + " userId: " + userId + " host: " + host + logger.debug("Testing cmdType: " + cmdType + " userId: " + userId + " host: " + host +
" port: " + port); " port: " + port);
SocksV4CmdRequest msg = new SocksV4CmdRequest(userId, cmdType, host, port); Socks4CmdRequest msg = new Socks4CmdRequest(userId, cmdType, host, port);
SocksV4CmdRequestDecoder decoder = new SocksV4CmdRequestDecoder(); Socks4CmdRequestDecoder decoder = new Socks4CmdRequestDecoder();
EmbeddedChannel embedder = new EmbeddedChannel(decoder); EmbeddedChannel embedder = new EmbeddedChannel(decoder);
SocksV4CommonTestUtils.writeMessageIntoEmbedder(embedder, msg); Socks4CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
Object obj = embedder.readInbound(); Object obj = embedder.readInbound();
msg = (SocksV4CmdRequest) obj; msg = (Socks4CmdRequest) obj;
assertSame(msg.cmdType(), cmdType); assertSame(msg.cmdType(), cmdType);
assertEquals(msg.userId(), userId); assertEquals(msg.userId(), userId);
assertEquals(msg.host(), host); assertEquals(msg.host(), host);
@ -57,7 +49,7 @@ public class SocksV4CmdRequestDecoderTest {
String[] hosts = {"127.0.0.1", }; String[] hosts = {"127.0.0.1", };
String[] userIds = {"test", }; String[] userIds = {"test", };
int[] ports = {1, 32769, 65535}; int[] ports = {1, 32769, 65535};
for (SocksV4CmdType cmdType : SocksV4CmdType.values()) { for (Socks4CmdType cmdType : Socks4CmdType.values()) {
for (String userId : userIds) { for (String userId : userIds) {
for (String host : hosts) { for (String host : hosts) {
for (int port : ports) { for (int port : ports) {

View File

@ -18,6 +18,6 @@ package io.netty.handler.codec.socksx.v4;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class SocksV4CmdRequestTest { public class Socks4CmdRequestTest {
private static final Logger logger = LoggerFactory.getLogger(SocksV4CmdRequestTest.class); private static final Logger logger = LoggerFactory.getLogger(Socks4CmdRequestTest.class);
} }

View File

@ -16,33 +16,29 @@
package io.netty.handler.codec.socksx.v4; package io.netty.handler.codec.socksx.v4;
import io.netty.channel.embedded.EmbeddedChannel; import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.socksx.v5.SocksV5AddressType;
import io.netty.handler.codec.socksx.v5.SocksV5CmdStatus;
import org.junit.Test; import org.junit.Test;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class SocksV4CmdResponseDecoderTest { public class Socks4CmdResponseDecoderTest {
private static final Logger logger = LoggerFactory.getLogger(SocksV4CmdResponseDecoderTest.class); private static final Logger logger = LoggerFactory.getLogger(Socks4CmdResponseDecoderTest.class);
private static void testSocksCmdResponseDecoderWithDifferentParams( private static void testSocksCmdResponseDecoderWithDifferentParams(
SocksV4CmdStatus cmdStatus, String host, int port) { Socks4CmdStatus cmdStatus, String host, int port) {
logger.debug("Testing cmdStatus: " + cmdStatus); logger.debug("Testing cmdStatus: " + cmdStatus);
SocksV4Response msg = new SocksV4CmdResponse(cmdStatus, host, port); Socks4Response msg = new Socks4CmdResponse(cmdStatus, host, port);
SocksV4CmdResponseDecoder decoder = new SocksV4CmdResponseDecoder(); Socks4CmdResponseDecoder decoder = new Socks4CmdResponseDecoder();
EmbeddedChannel embedder = new EmbeddedChannel(decoder); EmbeddedChannel embedder = new EmbeddedChannel(decoder);
SocksV4CommonTestUtils.writeMessageIntoEmbedder(embedder, msg); Socks4CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
msg = (SocksV4Response) embedder.readInbound(); msg = (Socks4Response) embedder.readInbound();
assertEquals(((SocksV4CmdResponse) msg).cmdStatus(), cmdStatus); assertEquals(((Socks4CmdResponse) msg).cmdStatus(), cmdStatus);
if (host != null) { if (host != null) {
assertEquals(((SocksV4CmdResponse) msg).host(), host); assertEquals(((Socks4CmdResponse) msg).host(), host);
} }
assertEquals(((SocksV4CmdResponse) msg).port(), port); assertEquals(((Socks4CmdResponse) msg).port(), port);
assertNull(embedder.readInbound()); assertNull(embedder.readInbound());
} }
@ -51,7 +47,7 @@ public class SocksV4CmdResponseDecoderTest {
*/ */
@Test @Test
public void testSocksCmdResponseDecoder() { public void testSocksCmdResponseDecoder() {
for (SocksV4CmdStatus cmdStatus : SocksV4CmdStatus.values()) { for (Socks4CmdStatus cmdStatus : Socks4CmdStatus.values()) {
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, null, 0); testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, null, 0);
} }
} }

View File

@ -18,6 +18,6 @@ package io.netty.handler.codec.socksx.v4;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class SocksV4CmdResponseTest { public class Socks4CmdResponseTest {
private static final Logger logger = LoggerFactory.getLogger(SocksV4CmdResponseTest.class); private static final Logger logger = LoggerFactory.getLogger(Socks4CmdResponseTest.class);
} }

View File

@ -18,18 +18,22 @@ package io.netty.handler.codec.socksx.v4;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.embedded.EmbeddedChannel; import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.socksx.SocksMessage;
final class SocksV4CommonTestUtils { final class Socks4CommonTestUtils {
/** /**
* A constructor to stop this class being constructed. * A constructor to stop this class being constructed.
*/ */
private SocksV4CommonTestUtils() { private Socks4CommonTestUtils() {
//NOOP //NOOP
} }
@SuppressWarnings("deprecation") public static void writeMessageIntoEmbedder(EmbeddedChannel embedder, Socks4Request msg) {
public static void writeMessageIntoEmbedder(EmbeddedChannel embedder, SocksMessage msg) { ByteBuf buf = Unpooled.buffer();
msg.encodeAsByteBuf(buf);
embedder.writeInbound(buf);
}
public static void writeMessageIntoEmbedder(EmbeddedChannel embedder, Socks4Response msg) {
ByteBuf buf = Unpooled.buffer(); ByteBuf buf = Unpooled.buffer();
msg.encodeAsByteBuf(buf); msg.encodeAsByteBuf(buf);
embedder.writeInbound(buf); embedder.writeInbound(buf);

View File

@ -20,17 +20,17 @@ import org.junit.Test;
import static org.junit.Assert.*; import static org.junit.Assert.*;
public class SocksV5AuthRequestDecoderTest { public class Socks5AuthRequestDecoderTest {
@Test @Test
public void testAuthRequestDecoder() { public void testAuthRequestDecoder() {
String username = "test"; String username = "test";
String password = "test"; String password = "test";
SocksV5AuthRequest msg = new SocksV5AuthRequest(username, password); Socks5AuthRequest msg = new Socks5AuthRequest(username, password);
SocksV5AuthRequestDecoder decoder = new SocksV5AuthRequestDecoder(); Socks5AuthRequestDecoder decoder = new Socks5AuthRequestDecoder();
EmbeddedChannel embedder = new EmbeddedChannel(decoder); EmbeddedChannel embedder = new EmbeddedChannel(decoder);
SocksV5CommonTestUtils.writeMessageIntoEmbedder(embedder, msg); Socks5CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
msg = (SocksV5AuthRequest) embedder.readInbound(); msg = (Socks5AuthRequest) embedder.readInbound();
assertEquals(msg.username(), username); assertEquals(msg.username(), username);
assertEquals(msg.username(), password); assertEquals(msg.username(), password);
assertNull(embedder.readInbound()); assertNull(embedder.readInbound());

View File

@ -18,16 +18,16 @@ package io.netty.handler.codec.socksx.v5;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
public class SocksV5AuthRequestTest { public class Socks5AuthRequestTest {
@Test @Test
public void testConstructorParamsAreNotNull() { public void testConstructorParamsAreNotNull() {
try { try {
new SocksV5AuthRequest(null, ""); new Socks5AuthRequest(null, "");
} catch (Exception e) { } catch (Exception e) {
assertTrue(e instanceof NullPointerException); assertTrue(e instanceof NullPointerException);
} }
try { try {
new SocksV5AuthRequest("", null); new Socks5AuthRequest("", null);
} catch (Exception e) { } catch (Exception e) {
assertTrue(e instanceof NullPointerException); assertTrue(e instanceof NullPointerException);
} }
@ -36,12 +36,12 @@ public class SocksV5AuthRequestTest {
@Test @Test
public void testUsernameOrPasswordIsNotAscii() { public void testUsernameOrPasswordIsNotAscii() {
try { try {
new SocksV5AuthRequest("παράδειγμα.δοκιμή", "password"); new Socks5AuthRequest("παράδειγμα.δοκιμή", "password");
} catch (Exception e) { } catch (Exception e) {
assertTrue(e instanceof IllegalArgumentException); assertTrue(e instanceof IllegalArgumentException);
} }
try { try {
new SocksV5AuthRequest("username", "παράδειγμα.δοκιμή"); new Socks5AuthRequest("username", "παράδειγμα.δοκιμή");
} catch (Exception e) { } catch (Exception e) {
assertTrue(e instanceof IllegalArgumentException); assertTrue(e instanceof IllegalArgumentException);
} }
@ -50,7 +50,7 @@ public class SocksV5AuthRequestTest {
@Test @Test
public void testUsernameOrPasswordLengthIsLessThan255Chars() { public void testUsernameOrPasswordLengthIsLessThan255Chars() {
try { try {
new SocksV5AuthRequest( new Socks5AuthRequest(
"passwordpasswordpasswordpasswordpasswordpasswordpassword" + "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
"passwordpasswordpasswordpasswordpasswordpasswordpassword" + "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
"passwordpasswordpasswordpasswordpasswordpasswordpassword" + "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
@ -64,7 +64,7 @@ public class SocksV5AuthRequestTest {
assertTrue(e instanceof IllegalArgumentException); assertTrue(e instanceof IllegalArgumentException);
} }
try { try {
new SocksV5AuthRequest("password", new Socks5AuthRequest("password",
"passwordpasswordpasswordpasswordpasswordpasswordpassword" + "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
"passwordpasswordpasswordpasswordpasswordpasswordpassword" + "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
"passwordpasswordpasswordpasswordpasswordpasswordpassword" + "passwordpasswordpasswordpasswordpasswordpasswordpassword" +

View File

@ -22,24 +22,24 @@ import org.junit.Test;
import static org.junit.Assert.*; import static org.junit.Assert.*;
public class SocksV5AuthResponseDecoderTest { public class Socks5AuthResponseDecoderTest {
private static final InternalLogger logger = InternalLoggerFactory.getInstance( private static final InternalLogger logger = InternalLoggerFactory.getInstance(
SocksV5AuthResponseDecoderTest.class); Socks5AuthResponseDecoderTest.class);
private static void testSocksAuthResponseDecoderWithDifferentParams(SocksV5AuthStatus authStatus) { private static void testSocksAuthResponseDecoderWithDifferentParams(Socks5AuthStatus authStatus) {
logger.debug("Testing SocksAuthResponseDecoder with authStatus: " + authStatus); logger.debug("Testing SocksAuthResponseDecoder with authStatus: " + authStatus);
SocksV5AuthResponse msg = new SocksV5AuthResponse(authStatus); Socks5AuthResponse msg = new Socks5AuthResponse(authStatus);
SocksV5AuthResponseDecoder decoder = new SocksV5AuthResponseDecoder(); Socks5AuthResponseDecoder decoder = new Socks5AuthResponseDecoder();
EmbeddedChannel embedder = new EmbeddedChannel(decoder); EmbeddedChannel embedder = new EmbeddedChannel(decoder);
SocksV5CommonTestUtils.writeMessageIntoEmbedder(embedder, msg); Socks5CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
msg = (SocksV5AuthResponse) embedder.readInbound(); msg = (Socks5AuthResponse) embedder.readInbound();
assertSame(msg.authStatus(), authStatus); assertSame(msg.authStatus(), authStatus);
assertNull(embedder.readInbound()); assertNull(embedder.readInbound());
} }
@Test @Test
public void testSocksCmdResponseDecoder() { public void testSocksCmdResponseDecoder() {
for (SocksV5AuthStatus authStatus: SocksV5AuthStatus.values()) { for (Socks5AuthStatus authStatus: Socks5AuthStatus.values()) {
testSocksAuthResponseDecoderWithDifferentParams(authStatus); testSocksAuthResponseDecoderWithDifferentParams(authStatus);
} }
} }

View File

@ -18,11 +18,11 @@ package io.netty.handler.codec.socksx.v5;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
public class SocksV5AuthResponseTest { public class Socks5AuthResponseTest {
@Test @Test
public void testConstructorParamsAreNotNull() { public void testConstructorParamsAreNotNull() {
try { try {
new SocksV5AuthResponse(null); new Socks5AuthResponse(null);
} catch (Exception e) { } catch (Exception e) {
assertTrue(e instanceof NullPointerException); assertTrue(e instanceof NullPointerException);
} }

View File

@ -23,23 +23,23 @@ import sun.net.util.IPAddressUtil;
import static org.junit.Assert.*; import static org.junit.Assert.*;
public class SocksV5CmdRequestDecoderTest { public class Socks5CmdRequestDecoderTest {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(SocksV5CmdRequestDecoderTest.class); private static final InternalLogger logger = InternalLoggerFactory.getInstance(Socks5CmdRequestDecoderTest.class);
private static void testSocksCmdRequestDecoderWithDifferentParams(SocksV5CmdType cmdType, private static void testSocksCmdRequestDecoderWithDifferentParams(Socks5CmdType cmdType,
SocksV5AddressType addressType, Socks5AddressType addressType,
String host, String host,
int port) { int port) {
logger.debug("Testing cmdType: " + cmdType + " addressType: " + addressType + " host: " + host + logger.debug("Testing cmdType: " + cmdType + " addressType: " + addressType + " host: " + host +
" port: " + port); " port: " + port);
SocksV5CmdRequest msg = new SocksV5CmdRequest(cmdType, addressType, host, port); Socks5CmdRequest msg = new Socks5CmdRequest(cmdType, addressType, host, port);
SocksV5CmdRequestDecoder decoder = new SocksV5CmdRequestDecoder(); Socks5CmdRequestDecoder decoder = new Socks5CmdRequestDecoder();
EmbeddedChannel embedder = new EmbeddedChannel(decoder); EmbeddedChannel embedder = new EmbeddedChannel(decoder);
SocksV5CommonTestUtils.writeMessageIntoEmbedder(embedder, msg); Socks5CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
if (msg.addressType() == SocksV5AddressType.UNKNOWN) { if (msg.addressType() == Socks5AddressType.UNKNOWN) {
assertTrue(embedder.readInbound() instanceof UnknownSocksV5Request); assertTrue(embedder.readInbound() instanceof UnknownSocks5Request);
} else { } else {
msg = (SocksV5CmdRequest) embedder.readInbound(); msg = (Socks5CmdRequest) embedder.readInbound();
assertSame(msg.cmdType(), cmdType); assertSame(msg.cmdType(), cmdType);
assertSame(msg.addressType(), addressType); assertSame(msg.addressType(), addressType);
assertEquals(msg.host(), host); assertEquals(msg.host(), host);
@ -52,10 +52,10 @@ public class SocksV5CmdRequestDecoderTest {
public void testCmdRequestDecoderIPv4() { public void testCmdRequestDecoderIPv4() {
String[] hosts = {"127.0.0.1", }; String[] hosts = {"127.0.0.1", };
int[] ports = {1, 32769, 65535 }; int[] ports = {1, 32769, 65535 };
for (SocksV5CmdType cmdType : SocksV5CmdType.values()) { for (Socks5CmdType cmdType : Socks5CmdType.values()) {
for (String host : hosts) { for (String host : hosts) {
for (int port : ports) { for (int port : ports) {
testSocksCmdRequestDecoderWithDifferentParams(cmdType, SocksV5AddressType.IPv4, host, port); testSocksCmdRequestDecoderWithDifferentParams(cmdType, Socks5AddressType.IPv4, host, port);
} }
} }
} }
@ -63,12 +63,12 @@ public class SocksV5CmdRequestDecoderTest {
@Test @Test
public void testCmdRequestDecoderIPv6() { public void testCmdRequestDecoderIPv6() {
String[] hosts = {SocksV5CommonUtils.ipv6toStr(IPAddressUtil.textToNumericFormatV6("::1"))}; String[] hosts = { Socks5CommonUtils.ipv6toStr(IPAddressUtil.textToNumericFormatV6("::1"))};
int[] ports = {1, 32769, 65535}; int[] ports = {1, 32769, 65535};
for (SocksV5CmdType cmdType : SocksV5CmdType.values()) { for (Socks5CmdType cmdType : Socks5CmdType.values()) {
for (String host : hosts) { for (String host : hosts) {
for (int port : ports) { for (int port : ports) {
testSocksCmdRequestDecoderWithDifferentParams(cmdType, SocksV5AddressType.IPv6, host, port); testSocksCmdRequestDecoderWithDifferentParams(cmdType, Socks5AddressType.IPv6, host, port);
} }
} }
} }
@ -89,10 +89,10 @@ public class SocksV5CmdRequestDecoderTest {
"실례.테스트", "실례.테스트",
"உதாரணம்.பரிட்சை"}; "உதாரணம்.பரிட்சை"};
int[] ports = {1, 32769, 65535}; int[] ports = {1, 32769, 65535};
for (SocksV5CmdType cmdType : SocksV5CmdType.values()) { for (Socks5CmdType cmdType : Socks5CmdType.values()) {
for (String host : hosts) { for (String host : hosts) {
for (int port : ports) { for (int port : ports) {
testSocksCmdRequestDecoderWithDifferentParams(cmdType, SocksV5AddressType.DOMAIN, host, port); testSocksCmdRequestDecoderWithDifferentParams(cmdType, Socks5AddressType.DOMAIN, host, port);
} }
} }
} }
@ -102,8 +102,8 @@ public class SocksV5CmdRequestDecoderTest {
public void testCmdRequestDecoderUnknown() { public void testCmdRequestDecoderUnknown() {
String host = "google.com"; String host = "google.com";
int port = 80; int port = 80;
for (SocksV5CmdType cmdType : SocksV5CmdType.values()) { for (Socks5CmdType cmdType : Socks5CmdType.values()) {
testSocksCmdRequestDecoderWithDifferentParams(cmdType, SocksV5AddressType.UNKNOWN, host, port); testSocksCmdRequestDecoderWithDifferentParams(cmdType, Socks5AddressType.UNKNOWN, host, port);
} }
} }
} }

View File

@ -19,23 +19,23 @@ import org.junit.Test;
import static org.junit.Assert.*; import static org.junit.Assert.*;
public class SocksV5CmdRequestTest { public class Socks5CmdRequestTest {
@Test @Test
public void testConstructorParamsAreNotNull() { public void testConstructorParamsAreNotNull() {
try { try {
new SocksV5CmdRequest(null, SocksV5AddressType.UNKNOWN, "", 1); new Socks5CmdRequest(null, Socks5AddressType.UNKNOWN, "", 1);
} catch (Exception e) { } catch (Exception e) {
assertTrue(e instanceof NullPointerException); assertTrue(e instanceof NullPointerException);
} }
try { try {
new SocksV5CmdRequest(SocksV5CmdType.UNKNOWN, null, "", 1); new Socks5CmdRequest(Socks5CmdType.UNKNOWN, null, "", 1);
} catch (Exception e) { } catch (Exception e) {
assertTrue(e instanceof NullPointerException); assertTrue(e instanceof NullPointerException);
} }
try { try {
new SocksV5CmdRequest(SocksV5CmdType.UNKNOWN, SocksV5AddressType.UNKNOWN, null, 1); new Socks5CmdRequest(Socks5CmdType.UNKNOWN, Socks5AddressType.UNKNOWN, null, 1);
} catch (Exception e) { } catch (Exception e) {
assertTrue(e instanceof NullPointerException); assertTrue(e instanceof NullPointerException);
} }
@ -44,7 +44,7 @@ public class SocksV5CmdRequestTest {
@Test @Test
public void testIPv4CorrectAddress() { public void testIPv4CorrectAddress() {
try { try {
new SocksV5CmdRequest(SocksV5CmdType.BIND, SocksV5AddressType.IPv4, "54.54.1111.253", 1); new Socks5CmdRequest(Socks5CmdType.BIND, Socks5AddressType.IPv4, "54.54.1111.253", 1);
} catch (Exception e) { } catch (Exception e) {
assertTrue(e instanceof IllegalArgumentException); assertTrue(e instanceof IllegalArgumentException);
} }
@ -53,7 +53,7 @@ public class SocksV5CmdRequestTest {
@Test @Test
public void testIPv6CorrectAddress() { public void testIPv6CorrectAddress() {
try { try {
new SocksV5CmdRequest(SocksV5CmdType.BIND, SocksV5AddressType.IPv6, "xxx:xxx:xxx", 1); new Socks5CmdRequest(Socks5CmdType.BIND, Socks5AddressType.IPv6, "xxx:xxx:xxx", 1);
} catch (Exception e) { } catch (Exception e) {
assertTrue(e instanceof IllegalArgumentException); assertTrue(e instanceof IllegalArgumentException);
} }
@ -62,7 +62,7 @@ public class SocksV5CmdRequestTest {
@Test @Test
public void testIDNNotExceeds255CharsLimit() { public void testIDNNotExceeds255CharsLimit() {
try { try {
new SocksV5CmdRequest(SocksV5CmdType.BIND, SocksV5AddressType.DOMAIN, new Socks5CmdRequest(Socks5CmdType.BIND, Socks5AddressType.DOMAIN,
"παράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμή" + "παράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμή" +
"παράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμή" + "παράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμή" +
"παράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμή" + "παράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμή" +
@ -75,14 +75,14 @@ public class SocksV5CmdRequestTest {
@Test @Test
public void testValidPortRange() { public void testValidPortRange() {
try { try {
new SocksV5CmdRequest(SocksV5CmdType.BIND, SocksV5AddressType.DOMAIN, new Socks5CmdRequest(Socks5CmdType.BIND, Socks5AddressType.DOMAIN,
"παράδειγμα.δοκιμήπαράδει", 0); "παράδειγμα.δοκιμήπαράδει", 0);
} catch (Exception e) { } catch (Exception e) {
assertTrue(e instanceof IllegalArgumentException); assertTrue(e instanceof IllegalArgumentException);
} }
try { try {
new SocksV5CmdRequest(SocksV5CmdType.BIND, SocksV5AddressType.DOMAIN, new Socks5CmdRequest(Socks5CmdType.BIND, Socks5AddressType.DOMAIN,
"παράδειγμα.δοκιμήπαράδει", 65536); "παράδειγμα.δοκιμήπαράδει", 65536);
} catch (Exception e) { } catch (Exception e) {
assertTrue(e instanceof IllegalArgumentException); assertTrue(e instanceof IllegalArgumentException);

View File

@ -22,25 +22,25 @@ import org.junit.Test;
import static org.junit.Assert.*; import static org.junit.Assert.*;
public class SocksV5CmdResponseDecoderTest { public class Socks5CmdResponseDecoderTest {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(SocksV5CmdResponseDecoderTest.class); private static final InternalLogger logger = InternalLoggerFactory.getInstance(Socks5CmdResponseDecoderTest.class);
private static void testSocksCmdResponseDecoderWithDifferentParams( private static void testSocksCmdResponseDecoderWithDifferentParams(
SocksV5CmdStatus cmdStatus, SocksV5AddressType addressType, String host, int port) { Socks5CmdStatus cmdStatus, Socks5AddressType addressType, String host, int port) {
logger.debug("Testing cmdStatus: " + cmdStatus + " addressType: " + addressType); logger.debug("Testing cmdStatus: " + cmdStatus + " addressType: " + addressType);
SocksV5Response msg = new SocksV5CmdResponse(cmdStatus, addressType, host, port); Socks5Response msg = new Socks5CmdResponse(cmdStatus, addressType, host, port);
SocksV5CmdResponseDecoder decoder = new SocksV5CmdResponseDecoder(); Socks5CmdResponseDecoder decoder = new Socks5CmdResponseDecoder();
EmbeddedChannel embedder = new EmbeddedChannel(decoder); EmbeddedChannel embedder = new EmbeddedChannel(decoder);
SocksV5CommonTestUtils.writeMessageIntoEmbedder(embedder, msg); Socks5CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
if (addressType == SocksV5AddressType.UNKNOWN) { if (addressType == Socks5AddressType.UNKNOWN) {
assertTrue(embedder.readInbound() instanceof UnknownSocksV5Response); assertTrue(embedder.readInbound() instanceof UnknownSocks5Response);
} else { } else {
msg = (SocksV5Response) embedder.readInbound(); msg = (Socks5Response) embedder.readInbound();
assertEquals(((SocksV5CmdResponse) msg).cmdStatus(), cmdStatus); assertEquals(((Socks5CmdResponse) msg).cmdStatus(), cmdStatus);
if (host != null) { if (host != null) {
assertEquals(((SocksV5CmdResponse) msg).host(), host); assertEquals(((Socks5CmdResponse) msg).host(), host);
} }
assertEquals(((SocksV5CmdResponse) msg).port(), port); assertEquals(((Socks5CmdResponse) msg).port(), port);
} }
assertNull(embedder.readInbound()); assertNull(embedder.readInbound());
} }
@ -50,8 +50,8 @@ public class SocksV5CmdResponseDecoderTest {
*/ */
@Test @Test
public void testSocksCmdResponseDecoder() { public void testSocksCmdResponseDecoder() {
for (SocksV5CmdStatus cmdStatus : SocksV5CmdStatus.values()) { for (Socks5CmdStatus cmdStatus : Socks5CmdStatus.values()) {
for (SocksV5AddressType addressType : SocksV5AddressType.values()) { for (Socks5AddressType addressType : Socks5AddressType.values()) {
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, addressType, null, 0); testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, addressType, null, 0);
} }
} }
@ -62,7 +62,7 @@ public class SocksV5CmdResponseDecoderTest {
*/ */
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void testInvalidAddress() { public void testInvalidAddress() {
testSocksCmdResponseDecoderWithDifferentParams(SocksV5CmdStatus.SUCCESS, SocksV5AddressType.IPv4, "1", 80); testSocksCmdResponseDecoderWithDifferentParams(Socks5CmdStatus.SUCCESS, Socks5AddressType.IPv4, "1", 80);
} }
/** /**
@ -70,14 +70,14 @@ public class SocksV5CmdResponseDecoderTest {
*/ */
@Test @Test
public void testSocksCmdResponseDecoderIncludingHost() { public void testSocksCmdResponseDecoderIncludingHost() {
for (SocksV5CmdStatus cmdStatus : SocksV5CmdStatus.values()) { for (Socks5CmdStatus cmdStatus : Socks5CmdStatus.values()) {
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, SocksV5AddressType.IPv4, testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, Socks5AddressType.IPv4,
"127.0.0.1", 80); "127.0.0.1", 80);
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, SocksV5AddressType.DOMAIN, testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, Socks5AddressType.DOMAIN,
"testDomain.com", 80); "testDomain.com", 80);
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, SocksV5AddressType.IPv6, testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, Socks5AddressType.IPv6,
"2001:db8:85a3:42:1000:8a2e:370:7334", 80); "2001:db8:85a3:42:1000:8a2e:370:7334", 80);
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, SocksV5AddressType.IPv6, testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, Socks5AddressType.IPv6,
"1111:111:11:1:0:0:0:1", 80); "1111:111:11:1:0:0:0:1", 80);
} }
} }

View File

@ -21,16 +21,16 @@ import org.junit.Test;
import static org.junit.Assert.*; import static org.junit.Assert.*;
public class SocksV5CmdResponseTest { public class Socks5CmdResponseTest {
@Test @Test
public void testConstructorParamsAreNotNull() { public void testConstructorParamsAreNotNull() {
try { try {
new SocksV5CmdResponse(null, SocksV5AddressType.UNKNOWN); new Socks5CmdResponse(null, Socks5AddressType.UNKNOWN);
} catch (Exception e) { } catch (Exception e) {
assertTrue(e instanceof NullPointerException); assertTrue(e instanceof NullPointerException);
} }
try { try {
new SocksV5CmdResponse(SocksV5CmdStatus.UNASSIGNED, null); new Socks5CmdResponse(Socks5CmdStatus.UNASSIGNED, null);
} catch (Exception e) { } catch (Exception e) {
assertTrue(e instanceof NullPointerException); assertTrue(e instanceof NullPointerException);
} }
@ -41,12 +41,12 @@ public class SocksV5CmdResponseTest {
*/ */
@Test @Test
public void testEmptyDomain() { public void testEmptyDomain() {
SocksV5CmdResponse socksV5CmdResponse = new SocksV5CmdResponse( Socks5CmdResponse socks5CmdResponse = new Socks5CmdResponse(
SocksV5CmdStatus.SUCCESS, SocksV5AddressType.DOMAIN); Socks5CmdStatus.SUCCESS, Socks5AddressType.DOMAIN);
assertNull(socksV5CmdResponse.host()); assertNull(socks5CmdResponse.host());
assertEquals(0, socksV5CmdResponse.port()); assertEquals(0, socks5CmdResponse.port());
ByteBuf buffer = Unpooled.buffer(20); ByteBuf buffer = Unpooled.buffer(20);
socksV5CmdResponse.encodeAsByteBuf(buffer); socks5CmdResponse.encodeAsByteBuf(buffer);
byte[] expected = { byte[] expected = {
0x05, // version 0x05, // version
0x00, // success reply 0x00, // success reply
@ -65,12 +65,12 @@ public class SocksV5CmdResponseTest {
*/ */
@Test @Test
public void testIPv4Host() { public void testIPv4Host() {
SocksV5CmdResponse socksV5CmdResponse = new SocksV5CmdResponse( Socks5CmdResponse socks5CmdResponse = new Socks5CmdResponse(
SocksV5CmdStatus.SUCCESS, SocksV5AddressType.IPv4, "127.0.0.1", 80); Socks5CmdStatus.SUCCESS, Socks5AddressType.IPv4, "127.0.0.1", 80);
assertEquals("127.0.0.1", socksV5CmdResponse.host()); assertEquals("127.0.0.1", socks5CmdResponse.host());
assertEquals(80, socksV5CmdResponse.port()); assertEquals(80, socks5CmdResponse.port());
ByteBuf buffer = Unpooled.buffer(20); ByteBuf buffer = Unpooled.buffer(20);
socksV5CmdResponse.encodeAsByteBuf(buffer); socks5CmdResponse.encodeAsByteBuf(buffer);
byte[] expected = { byte[] expected = {
0x05, // version 0x05, // version
0x00, // success reply 0x00, // success reply
@ -91,12 +91,12 @@ public class SocksV5CmdResponseTest {
*/ */
@Test @Test
public void testEmptyBoundAddress() { public void testEmptyBoundAddress() {
SocksV5CmdResponse socksV5CmdResponse = new SocksV5CmdResponse( Socks5CmdResponse socks5CmdResponse = new Socks5CmdResponse(
SocksV5CmdStatus.SUCCESS, SocksV5AddressType.DOMAIN, "", 80); Socks5CmdStatus.SUCCESS, Socks5AddressType.DOMAIN, "", 80);
assertEquals("", socksV5CmdResponse.host()); assertEquals("", socks5CmdResponse.host());
assertEquals(80, socksV5CmdResponse.port()); assertEquals(80, socks5CmdResponse.port());
ByteBuf buffer = Unpooled.buffer(20); ByteBuf buffer = Unpooled.buffer(20);
socksV5CmdResponse.encodeAsByteBuf(buffer); socks5CmdResponse.encodeAsByteBuf(buffer);
byte[] expected = { byte[] expected = {
0x05, // version 0x05, // version
0x00, // success reply 0x00, // success reply
@ -114,7 +114,7 @@ public class SocksV5CmdResponseTest {
*/ */
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void testInvalidBoundAddress() { public void testInvalidBoundAddress() {
new SocksV5CmdResponse(SocksV5CmdStatus.SUCCESS, SocksV5AddressType.IPv4, "127.0.0", 1000); new Socks5CmdResponse(Socks5CmdStatus.SUCCESS, Socks5AddressType.IPv4, "127.0.0", 1000);
} }
private static void assertByteBufEquals(byte[] expected, ByteBuf actual) { private static void assertByteBufEquals(byte[] expected, ByteBuf actual) {
@ -127,13 +127,13 @@ public class SocksV5CmdResponseTest {
@Test @Test
public void testValidPortRange() { public void testValidPortRange() {
try { try {
new SocksV5CmdResponse(SocksV5CmdStatus.SUCCESS, SocksV5AddressType.IPv4, "127.0.0", 0); new Socks5CmdResponse(Socks5CmdStatus.SUCCESS, Socks5AddressType.IPv4, "127.0.0", 0);
} catch (Exception e) { } catch (Exception e) {
assertTrue(e instanceof IllegalArgumentException); assertTrue(e instanceof IllegalArgumentException);
} }
try { try {
new SocksV5CmdResponse(SocksV5CmdStatus.SUCCESS, SocksV5AddressType.IPv4, "127.0.0", 65536); new Socks5CmdResponse(Socks5CmdStatus.SUCCESS, Socks5AddressType.IPv4, "127.0.0", 65536);
} catch (Exception e) { } catch (Exception e) {
assertTrue(e instanceof IllegalArgumentException); assertTrue(e instanceof IllegalArgumentException);
} }

View File

@ -18,18 +18,22 @@ package io.netty.handler.codec.socksx.v5;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.embedded.EmbeddedChannel; import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.socksx.SocksMessage;
final class SocksV5CommonTestUtils { final class Socks5CommonTestUtils {
/** /**
* A constructor to stop this class being constructed. * A constructor to stop this class being constructed.
*/ */
private SocksV5CommonTestUtils() { private Socks5CommonTestUtils() {
//NOOP //NOOP
} }
@SuppressWarnings("deprecation") public static void writeMessageIntoEmbedder(EmbeddedChannel embedder, Socks5Request msg) {
public static void writeMessageIntoEmbedder(EmbeddedChannel embedder, SocksMessage msg) { ByteBuf buf = Unpooled.buffer();
msg.encodeAsByteBuf(buf);
embedder.writeInbound(buf);
}
public static void writeMessageIntoEmbedder(EmbeddedChannel embedder, Socks5Response msg) {
ByteBuf buf = Unpooled.buffer(); ByteBuf buf = Unpooled.buffer();
msg.encodeAsByteBuf(buf); msg.encodeAsByteBuf(buf);
embedder.writeInbound(buf); embedder.writeInbound(buf);

View File

@ -18,11 +18,11 @@ package io.netty.handler.codec.socksx.v5;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
public class SocksV5InitRequestTest { public class Socks5InitRequestTest {
@Test @Test
public void testConstructorParamsAreNotNull() { public void testConstructorParamsAreNotNull() {
try { try {
new SocksV5InitRequest(null); new Socks5InitRequest(null);
} catch (Exception e) { } catch (Exception e) {
assertTrue(e instanceof NullPointerException); assertTrue(e instanceof NullPointerException);
} }

View File

@ -18,11 +18,11 @@ package io.netty.handler.codec.socksx.v5;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
public class SocksV5InitResponseTest { public class Socks5InitResponseTest {
@Test @Test
public void testConstructorParamsAreNotNull() { public void testConstructorParamsAreNotNull() {
try { try {
new SocksV5InitResponse(null); new Socks5InitResponse(null);
} catch (Exception e) { } catch (Exception e) {
assertTrue(e instanceof NullPointerException); assertTrue(e instanceof NullPointerException);
} }

View File

@ -19,10 +19,11 @@ import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.socksx.SocksMessageEncoder;
import io.netty.handler.codec.socksx.SocksProtocolVersion; import io.netty.handler.codec.socksx.SocksProtocolVersion;
import io.netty.handler.codec.socksx.v4.SocksV4CmdRequestDecoder; import io.netty.handler.codec.socksx.v4.Socks4CmdRequestDecoder;
import io.netty.handler.codec.socksx.v5.SocksV5InitRequestDecoder; import io.netty.handler.codec.socksx.v4.Socks4MessageEncoder;
import io.netty.handler.codec.socksx.v5.Socks5InitRequestDecoder;
import io.netty.handler.codec.socksx.v5.Socks5MessageEncoder;
import java.util.List; import java.util.List;
@ -35,18 +36,21 @@ public class SocksPortUnificationServerHandler extends ByteToMessageDecoder {
in.resetReaderIndex(); in.resetReaderIndex();
switch (version) { switch (version) {
case SOCKS4a: case SOCKS4a:
p.addLast(new SocksV4CmdRequestDecoder()); p.addLast(new Socks4CmdRequestDecoder());
p.addLast(Socks4MessageEncoder.INSTANCE);
break; break;
case SOCKS5: case SOCKS5:
p.addLast(new SocksV5InitRequestDecoder()); p.addLast(new Socks5InitRequestDecoder());
p.addLast(Socks5MessageEncoder.INSTANCE);
break; break;
case UNKNOWN: case UNKNOWN:
in.clear(); in.clear();
ctx.close(); ctx.close();
return; return;
} }
p.addLast(SocksMessageEncoder.getInstance()); p.addLast(SocksServerHandler.INSTANCE);
p.addLast(SocksServerHandler.getInstance());
p.remove(this); p.remove(this);
} }
} }

View File

@ -24,17 +24,13 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOption; import io.netty.channel.ChannelOption;
import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.socks.SocksCmdRequest;
import io.netty.handler.codec.socks.SocksCmdResponse;
import io.netty.handler.codec.socks.SocksCmdStatus;
import io.netty.handler.codec.socksx.SocksMessage;
import io.netty.handler.codec.socksx.SocksRequest; import io.netty.handler.codec.socksx.SocksRequest;
import io.netty.handler.codec.socksx.v4.SocksV4CmdRequest; import io.netty.handler.codec.socksx.v4.Socks4CmdRequest;
import io.netty.handler.codec.socksx.v4.SocksV4CmdResponse; import io.netty.handler.codec.socksx.v4.Socks4CmdResponse;
import io.netty.handler.codec.socksx.v4.SocksV4CmdStatus; import io.netty.handler.codec.socksx.v4.Socks4CmdStatus;
import io.netty.handler.codec.socksx.v5.SocksV5CmdRequest; import io.netty.handler.codec.socksx.v5.Socks5CmdRequest;
import io.netty.handler.codec.socksx.v5.SocksV5CmdResponse; import io.netty.handler.codec.socksx.v5.Socks5CmdResponse;
import io.netty.handler.codec.socksx.v5.SocksV5CmdStatus; import io.netty.handler.codec.socksx.v5.Socks5CmdStatus;
import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener; import io.netty.util.concurrent.GenericFutureListener;
import io.netty.util.concurrent.Promise; import io.netty.util.concurrent.Promise;
@ -46,8 +42,8 @@ public final class SocksServerConnectHandler extends SimpleChannelInboundHandler
@Override @Override
public void messageReceived(final ChannelHandlerContext ctx, final SocksRequest message) throws Exception { public void messageReceived(final ChannelHandlerContext ctx, final SocksRequest message) throws Exception {
if (message instanceof SocksV4CmdRequest) { if (message instanceof Socks4CmdRequest) {
final SocksV4CmdRequest request = (SocksV4CmdRequest) message; final Socks4CmdRequest request = (Socks4CmdRequest) message;
Promise<Channel> promise = ctx.executor().newPromise(); Promise<Channel> promise = ctx.executor().newPromise();
promise.addListener( promise.addListener(
new GenericFutureListener<Future<Channel>>() { new GenericFutureListener<Future<Channel>>() {
@ -55,7 +51,7 @@ public final class SocksServerConnectHandler extends SimpleChannelInboundHandler
public void operationComplete(final Future<Channel> future) throws Exception { public void operationComplete(final Future<Channel> future) throws Exception {
final Channel outboundChannel = future.getNow(); final Channel outboundChannel = future.getNow();
if (future.isSuccess()) { if (future.isSuccess()) {
ctx.channel().writeAndFlush(new SocksV4CmdResponse(SocksV4CmdStatus.SUCCESS)) ctx.channel().writeAndFlush(new Socks4CmdResponse(Socks4CmdStatus.SUCCESS))
.addListener(new ChannelFutureListener() { .addListener(new ChannelFutureListener() {
@Override @Override
public void operationComplete(ChannelFuture channelFuture) { public void operationComplete(ChannelFuture channelFuture) {
@ -66,7 +62,7 @@ public final class SocksServerConnectHandler extends SimpleChannelInboundHandler
}); });
} else { } else {
ctx.channel().writeAndFlush( ctx.channel().writeAndFlush(
new SocksV4CmdResponse(SocksV4CmdStatus.REJECTED_OR_FAILED) new Socks4CmdResponse(Socks4CmdStatus.REJECTED_OR_FAILED)
); );
SocksServerUtils.closeOnFlush(ctx.channel()); SocksServerUtils.closeOnFlush(ctx.channel());
} }
@ -88,14 +84,14 @@ public final class SocksServerConnectHandler extends SimpleChannelInboundHandler
} else { } else {
// Close the connection if the connection attempt has failed. // Close the connection if the connection attempt has failed.
ctx.channel().writeAndFlush( ctx.channel().writeAndFlush(
new SocksV4CmdResponse(SocksV4CmdStatus.REJECTED_OR_FAILED) new Socks4CmdResponse(Socks4CmdStatus.REJECTED_OR_FAILED)
); );
SocksServerUtils.closeOnFlush(ctx.channel()); SocksServerUtils.closeOnFlush(ctx.channel());
} }
} }
}); });
} else if (message instanceof SocksV5CmdRequest) { } else if (message instanceof Socks5CmdRequest) {
final SocksV5CmdRequest request = (SocksV5CmdRequest) message; final Socks5CmdRequest request = (Socks5CmdRequest) message;
Promise<Channel> promise = ctx.executor().newPromise(); Promise<Channel> promise = ctx.executor().newPromise();
promise.addListener( promise.addListener(
new GenericFutureListener<Future<Channel>>() { new GenericFutureListener<Future<Channel>>() {
@ -104,7 +100,7 @@ public final class SocksServerConnectHandler extends SimpleChannelInboundHandler
final Channel outboundChannel = future.getNow(); final Channel outboundChannel = future.getNow();
if (future.isSuccess()) { if (future.isSuccess()) {
ctx.channel().writeAndFlush( ctx.channel().writeAndFlush(
new SocksV5CmdResponse(SocksV5CmdStatus.SUCCESS, request.addressType()) new Socks5CmdResponse(Socks5CmdStatus.SUCCESS, request.addressType())
).addListener(new ChannelFutureListener() { ).addListener(new ChannelFutureListener() {
@Override @Override
public void operationComplete(ChannelFuture channelFuture) { public void operationComplete(ChannelFuture channelFuture) {
@ -116,7 +112,7 @@ public final class SocksServerConnectHandler extends SimpleChannelInboundHandler
); );
} else { } else {
ctx.channel().writeAndFlush( ctx.channel().writeAndFlush(
new SocksV5CmdResponse(SocksV5CmdStatus.FAILURE, request.addressType())); new Socks5CmdResponse(Socks5CmdStatus.FAILURE, request.addressType()));
SocksServerUtils.closeOnFlush(ctx.channel()); SocksServerUtils.closeOnFlush(ctx.channel());
} }
} }
@ -137,7 +133,7 @@ public final class SocksServerConnectHandler extends SimpleChannelInboundHandler
} else { } else {
// Close the connection if the connection attempt has failed. // Close the connection if the connection attempt has failed.
ctx.channel().writeAndFlush( ctx.channel().writeAndFlush(
new SocksV5CmdResponse(SocksV5CmdStatus.FAILURE, request.addressType())); new Socks5CmdResponse(Socks5CmdStatus.FAILURE, request.addressType()));
SocksServerUtils.closeOnFlush(ctx.channel()); SocksServerUtils.closeOnFlush(ctx.channel());
} }
} }

View File

@ -19,26 +19,30 @@ import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.socksx.SocksRequest; import io.netty.handler.codec.socksx.SocksRequest;
import io.netty.handler.codec.socksx.v4.SocksV4CmdRequest; import io.netty.handler.codec.socksx.v4.Socks4CmdRequest;
import io.netty.handler.codec.socksx.v4.SocksV4CmdType; import io.netty.handler.codec.socksx.v4.Socks4CmdType;
import io.netty.handler.codec.socksx.v5.SocksV5AuthScheme; import io.netty.handler.codec.socksx.v5.Socks5AuthScheme;
import io.netty.handler.codec.socksx.v5.SocksV5CmdRequestDecoder; import io.netty.handler.codec.socksx.v5.Socks5CmdRequestDecoder;
import io.netty.handler.codec.socksx.v5.SocksV5InitResponse; import io.netty.handler.codec.socksx.v5.Socks5InitResponse;
import io.netty.handler.codec.socksx.v5.SocksV5Request; import io.netty.handler.codec.socksx.v5.Socks5Request;
import io.netty.handler.codec.socksx.v5.SocksV5AuthResponse; import io.netty.handler.codec.socksx.v5.Socks5AuthResponse;
import io.netty.handler.codec.socksx.v5.SocksV5AuthStatus; import io.netty.handler.codec.socksx.v5.Socks5AuthStatus;
import io.netty.handler.codec.socksx.v5.SocksV5CmdRequest; import io.netty.handler.codec.socksx.v5.Socks5CmdRequest;
import io.netty.handler.codec.socksx.v5.SocksV5CmdType; import io.netty.handler.codec.socksx.v5.Socks5CmdType;
@ChannelHandler.Sharable @ChannelHandler.Sharable
public final class SocksServerHandler extends SimpleChannelInboundHandler<SocksRequest> { public final class SocksServerHandler extends SimpleChannelInboundHandler<SocksRequest> {
public static final SocksServerHandler INSTANCE = new SocksServerHandler();
private SocksServerHandler() { }
@Override @Override
public void messageReceived(ChannelHandlerContext ctx, SocksRequest socksRequest) throws Exception { public void messageReceived(ChannelHandlerContext ctx, SocksRequest socksRequest) throws Exception {
switch (socksRequest.protocolVersion()) { switch (socksRequest.protocolVersion()) {
case SOCKS4a: case SOCKS4a:
SocksV4CmdRequest socksV4CmdRequest = (SocksV4CmdRequest) socksRequest; Socks4CmdRequest socksV4CmdRequest = (Socks4CmdRequest) socksRequest;
if (socksV4CmdRequest.cmdType() == SocksV4CmdType.CONNECT) { if (socksV4CmdRequest.cmdType() == Socks4CmdType.CONNECT) {
ctx.pipeline().addLast(new SocksServerConnectHandler()); ctx.pipeline().addLast(new SocksServerConnectHandler());
ctx.pipeline().remove(this); ctx.pipeline().remove(this);
ctx.fireChannelRead(socksRequest); ctx.fireChannelRead(socksRequest);
@ -47,22 +51,22 @@ public final class SocksServerHandler extends SimpleChannelInboundHandler<SocksR
} }
break; break;
case SOCKS5: case SOCKS5:
switch (((SocksV5Request) socksRequest).requestType()) { switch (((Socks5Request) socksRequest).requestType()) {
case INIT: { case INIT: {
// auth support example // auth support example
//ctx.pipeline().addFirst(new SocksV5AuthRequestDecoder()); //ctx.pipeline().addFirst(new SocksV5AuthRequestDecoder());
//ctx.write(new SocksV5InitResponse(SocksV5AuthScheme.AUTH_PASSWORD)); //ctx.write(new SocksV5InitResponse(SocksV5AuthScheme.AUTH_PASSWORD));
ctx.pipeline().addFirst(new SocksV5CmdRequestDecoder()); ctx.pipeline().addFirst(new Socks5CmdRequestDecoder());
ctx.write(new SocksV5InitResponse(SocksV5AuthScheme.NO_AUTH)); ctx.write(new Socks5InitResponse(Socks5AuthScheme.NO_AUTH));
break; break;
} }
case AUTH: case AUTH:
ctx.pipeline().addFirst(new SocksV5CmdRequestDecoder()); ctx.pipeline().addFirst(new Socks5CmdRequestDecoder());
ctx.write(new SocksV5AuthResponse(SocksV5AuthStatus.SUCCESS)); ctx.write(new Socks5AuthResponse(Socks5AuthStatus.SUCCESS));
break; break;
case CMD: case CMD:
SocksV5CmdRequest socksV5CmdRequest = (SocksV5CmdRequest) socksRequest; Socks5CmdRequest socks5CmdRequest = (Socks5CmdRequest) socksRequest;
if (socksV5CmdRequest.cmdType() == SocksV5CmdType.CONNECT) { if (socks5CmdRequest.cmdType() == Socks5CmdType.CONNECT) {
ctx.pipeline().addLast(new SocksServerConnectHandler()); ctx.pipeline().addLast(new SocksServerConnectHandler());
ctx.pipeline().remove(this); ctx.pipeline().remove(this);
ctx.fireChannelRead(socksRequest); ctx.fireChannelRead(socksRequest);
@ -91,12 +95,4 @@ public final class SocksServerHandler extends SimpleChannelInboundHandler<SocksR
throwable.printStackTrace(); throwable.printStackTrace();
SocksServerUtils.closeOnFlush(ctx.channel()); SocksServerUtils.closeOnFlush(ctx.channel());
} }
private static class SocksServerHandlerHolder {
public static final SocksServerHandler HOLDER_INSTANCE = new SocksServerHandler();
}
public static SocksServerHandler getInstance() {
return SocksServerHandlerHolder.HOLDER_INSTANCE;
}
} }