// Path: dragonite-proxy/src/main/java/com/vecsight/dragonite/proxy/exception/IncorrectHeaderException.java
// public class IncorrectHeaderException extends Exception {
// 
//     public IncorrectHeaderException(final String msg) {
//         super(msg);
//     }
// 
// }
// 
// Path: dragonite-proxy/src/main/java/com/vecsight/dragonite/proxy/misc/ProxyGlobalConstants.java
// public final class ProxyGlobalConstants {
// 
//     public static final String APP_VERSION = ProxyBuildConfig.VERSION;
// 
//     public static final byte PROTOCOL_VERSION = 2;
// 
//     public static final int DEFAULT_SERVER_PORT = 5234;
// 
//     public static final long INIT_SEND_SPEED = 100 * 1024; //100kb/s
// 
//     public static final Charset STRING_CHARSET = StandardCharsets.UTF_8;
// 
//     public static final Charset HEADER_ADDRESS_CHARSET = StandardCharsets.US_ASCII;
// 
//     public static final short PIPE_BUFFER_SIZE = 10240;
// 
//     public static final short MAX_FRAME_SIZE = 20480;
// 
//     public static final int PASSWORD_MIN_LENGTH = 4;
// 
//     public static final int SOCKS5_PORT = 1080;
// 
//     public static final int TCP_CONNECT_TIMEOUT_MS = 4000;
// 
//     public static final String UPDATE_API_URL = "https://github.com/dragonite-network/dragonite-java/raw/master/VERSIONS";
// 
//     public static final String UPDATE_API_PRODUCT_NAME = "proxy";
// 
// }
// 
// Path: dragonite-utils/src/main/java/com/vecsight/dragonite/utils/binary/BinaryReader.java
// public class BinaryReader {
// 
//     private final ByteBuffer byteBuffer;
// 
//     public BinaryReader(final byte[] bytes) {
//         byteBuffer = ByteBuffer.wrap(bytes);
//     }
// 
//     public byte getSignedByte() {
//         return byteBuffer.get();
//     }
// 
//     public short getUnsignedByte() {
//         return (short) (byteBuffer.get() & (short) 0xff);
//     }
// 
//     public short getSignedShort() {
//         return byteBuffer.getShort();
//     }
// 
//     public int getUnsignedShort() {
//         return byteBuffer.getShort() & 0xffff;
//     }
// 
//     public int getSignedInt() {
//         return byteBuffer.getInt();
//     }
// 
//     public long getUnsignedInt() {
//         return (long) byteBuffer.getInt() & 0xffffffffL;
//     }
// 
//     public void getBytes(final byte[] bytes) {
//         byteBuffer.get(bytes);
//     }
// 
//     public byte[] getBytesGroupWithByteLength() {
//         final short len = getUnsignedByte();
//         final byte[] bytes = new byte[len];
//         byteBuffer.get(bytes);
//         return bytes;
//     }
// 
//     public byte[] getBytesGroupWithShortLength() {
//         final int len = getUnsignedShort();
//         final byte[] bytes = new byte[len];
//         byteBuffer.get(bytes);
//         return bytes;
//     }
// 
//     public boolean getBoolean() {
//         return byteBuffer.get() != 0;
//     }
// 
//     public int remaining() {
//         return byteBuffer.remaining();
//     }
// 
// }
// 
// Path: dragonite-utils/src/main/java/com/vecsight/dragonite/utils/binary/BinaryWriter.java
// public class BinaryWriter {
// 
//     private final ByteBuffer byteBuffer;
// 
//     public BinaryWriter(final int capacity) {
//         byteBuffer = ByteBuffer.allocate(capacity);
//     }
// 
//     public BinaryWriter putSignedByte(final byte sb) {
//         byteBuffer.put(sb);
//         return this;
//     }
// 
//     public BinaryWriter putUnsignedByte(final short ub) {
//         byteBuffer.put((byte) (ub & 0xff));
//         return this;
//     }
// 
//     public BinaryWriter putSignedShort(final short ss) {
//         byteBuffer.putShort(ss);
//         return this;
//     }
// 
//     public BinaryWriter putUnsignedShort(final int us) {
//         byteBuffer.putShort((short) (us & 0xffff));
//         return this;
//     }
// 
//     public BinaryWriter putSignedInt(final int si) {
//         byteBuffer.putInt(si);
//         return this;
//     }
// 
//     public BinaryWriter putUnsignedInt(final long ui) {
//         byteBuffer.putInt((int) (ui & 0xffffffffL));
//         return this;
//     }
// 
//     public BinaryWriter putBytes(final byte[] bytes) {
//         byteBuffer.put(bytes);
//         return this;
//     }
// 
//     public BinaryWriter putBytesGroupWithByteLength(final byte[] bytes) {
//         putUnsignedByte((short) bytes.length);
//         putBytes(bytes);
//         return this;
//     }
// 
//     public BinaryWriter putBytesGroupWithShortLength(final byte[] bytes) {
//         putUnsignedShort(bytes.length);
//         putBytes(bytes);
//         return this;
//     }
// 
//     public BinaryWriter putBoolean(final boolean b) {
//         byteBuffer.put((byte) (b ? 1 : 0));
//         return this;
//     }
// 
//     public byte[] toBytes() {
//         return byteBuffer.array();
//     }
// 
// }


import com.vecsight.dragonite.proxy.exception.IncorrectHeaderException;
import com.vecsight.dragonite.proxy.misc.ProxyGlobalConstants;
import com.vecsight.dragonite.utils.binary.BinaryReader;
import com.vecsight.dragonite.utils.binary.BinaryWriter;
import java.nio.BufferUnderflowException;
/*
 * The Dragonite Project
 * -------------------------
 * See the LICENSE file in the root directory for license information.
 */


package com.vecsight.dragonite.proxy.header;



/*
 * VERSION  1 SB
 * status   1 SB
 * msgLen   2 US
 * msg      [length]
 */

public class ServerResponseHeader {

    private static final byte VERSION = ProxyGlobalConstants.PROTOCOL_VERSION;

    public static final int FIXED_LENGTH = 4;

    private byte status;

    private String msg;

    public ServerResponseHeader(final byte status, final String msg) {
        this.status = status;
        this.msg = msg;
    }

// Path: dragonite-proxy/src/main/java/com/vecsight/dragonite/proxy/exception/IncorrectHeaderException.java
// public class IncorrectHeaderException extends Exception {
// 
//     public IncorrectHeaderException(final String msg) {
//         super(msg);
//     }
// 
// }
// 
// Path: dragonite-proxy/src/main/java/com/vecsight/dragonite/proxy/misc/ProxyGlobalConstants.java
// public final class ProxyGlobalConstants {
// 
//     public static final String APP_VERSION = ProxyBuildConfig.VERSION;
// 
//     public static final byte PROTOCOL_VERSION = 2;
// 
//     public static final int DEFAULT_SERVER_PORT = 5234;
// 
//     public static final long INIT_SEND_SPEED = 100 * 1024; //100kb/s
// 
//     public static final Charset STRING_CHARSET = StandardCharsets.UTF_8;
// 
//     public static final Charset HEADER_ADDRESS_CHARSET = StandardCharsets.US_ASCII;
// 
//     public static final short PIPE_BUFFER_SIZE = 10240;
// 
//     public static final short MAX_FRAME_SIZE = 20480;
// 
//     public static final int PASSWORD_MIN_LENGTH = 4;
// 
//     public static final int SOCKS5_PORT = 1080;
// 
//     public static final int TCP_CONNECT_TIMEOUT_MS = 4000;
// 
//     public static final String UPDATE_API_URL = "https://github.com/dragonite-network/dragonite-java/raw/master/VERSIONS";
// 
//     public static final String UPDATE_API_PRODUCT_NAME = "proxy";
// 
// }
// 
// Path: dragonite-utils/src/main/java/com/vecsight/dragonite/utils/binary/BinaryReader.java
// public class BinaryReader {
// 
//     private final ByteBuffer byteBuffer;
// 
//     public BinaryReader(final byte[] bytes) {
//         byteBuffer = ByteBuffer.wrap(bytes);
//     }
// 
//     public byte getSignedByte() {
//         return byteBuffer.get();
//     }
// 
//     public short getUnsignedByte() {
//         return (short) (byteBuffer.get() & (short) 0xff);
//     }
// 
//     public short getSignedShort() {
//         return byteBuffer.getShort();
//     }
// 
//     public int getUnsignedShort() {
//         return byteBuffer.getShort() & 0xffff;
//     }
// 
//     public int getSignedInt() {
//         return byteBuffer.getInt();
//     }
// 
//     public long getUnsignedInt() {
//         return (long) byteBuffer.getInt() & 0xffffffffL;
//     }
// 
//     public void getBytes(final byte[] bytes) {
//         byteBuffer.get(bytes);
//     }
// 
//     public byte[] getBytesGroupWithByteLength() {
//         final short len = getUnsignedByte();
//         final byte[] bytes = new byte[len];
//         byteBuffer.get(bytes);
//         return bytes;
//     }
// 
//     public byte[] getBytesGroupWithShortLength() {
//         final int len = getUnsignedShort();
//         final byte[] bytes = new byte[len];
//         byteBuffer.get(bytes);
//         return bytes;
//     }
// 
//     public boolean getBoolean() {
//         return byteBuffer.get() != 0;
//     }
// 
//     public int remaining() {
//         return byteBuffer.remaining();
//     }
// 
// }
// 
// Path: dragonite-utils/src/main/java/com/vecsight/dragonite/utils/binary/BinaryWriter.java
// public class BinaryWriter {
// 
//     private final ByteBuffer byteBuffer;
// 
//     public BinaryWriter(final int capacity) {
//         byteBuffer = ByteBuffer.allocate(capacity);
//     }
// 
//     public BinaryWriter putSignedByte(final byte sb) {
//         byteBuffer.put(sb);
//         return this;
//     }
// 
//     public BinaryWriter putUnsignedByte(final short ub) {
//         byteBuffer.put((byte) (ub & 0xff));
//         return this;
//     }
// 
//     public BinaryWriter putSignedShort(final short ss) {
//         byteBuffer.putShort(ss);
//         return this;
//     }
// 
//     public BinaryWriter putUnsignedShort(final int us) {
//         byteBuffer.putShort((short) (us & 0xffff));
//         return this;
//     }
// 
//     public BinaryWriter putSignedInt(final int si) {
//         byteBuffer.putInt(si);
//         return this;
//     }
// 
//     public BinaryWriter putUnsignedInt(final long ui) {
//         byteBuffer.putInt((int) (ui & 0xffffffffL));
//         return this;
//     }
// 
//     public BinaryWriter putBytes(final byte[] bytes) {
//         byteBuffer.put(bytes);
//         return this;
//     }
// 
//     public BinaryWriter putBytesGroupWithByteLength(final byte[] bytes) {
//         putUnsignedByte((short) bytes.length);
//         putBytes(bytes);
//         return this;
//     }
// 
//     public BinaryWriter putBytesGroupWithShortLength(final byte[] bytes) {
//         putUnsignedShort(bytes.length);
//         putBytes(bytes);
//         return this;
//     }
// 
//     public BinaryWriter putBoolean(final boolean b) {
//         byteBuffer.put((byte) (b ? 1 : 0));
//         return this;
//     }
// 
//     public byte[] toBytes() {
//         return byteBuffer.array();
//     }
// 
// }


// Path: dragonite-proxy/src/main/java/com/vecsight/dragonite/proxy/header/ServerResponseHeader.java
import com.vecsight.dragonite.proxy.exception.IncorrectHeaderException;
import com.vecsight.dragonite.proxy.misc.ProxyGlobalConstants;
import com.vecsight.dragonite.utils.binary.BinaryReader;
import com.vecsight.dragonite.utils.binary.BinaryWriter;
import java.nio.BufferUnderflowException;

/*
 * The Dragonite Project
 * -------------------------
 * See the LICENSE file in the root directory for license information.
 */


package com.vecsight.dragonite.proxy.header;



/*
 * VERSION  1 SB
 * status   1 SB
 * msgLen   2 US
 * msg      [length]
 */

public class ServerResponseHeader {

    private static final byte VERSION = ProxyGlobalConstants.PROTOCOL_VERSION;

    public static final int FIXED_LENGTH = 4;

    private byte status;

    private String msg;

    public ServerResponseHeader(final byte status, final String msg) {
        this.status = status;
        this.msg = msg;
    }

    public ServerResponseHeader(final byte[] header) throws IncorrectHeaderException {