为什么我的本地Java代理可以在Eclipse中工作,但不能在Android中正常工作?

时间:2019-04-23 06:16:11

标签: android proxy

我创建了一个本地代理服务器来拦截所有网络流量。该代码拦截http / https流量。代理可以在Eclipse中正常工作,但是当我将其与android项目集成时,它仅适用于http流量。

最初,它不适用于http流量,这还因为未在Android中保护套接字不受VpnService的攻击。一旦通道的套接字被保护为http,它就可以正常工作。

import java.io.*;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.regex.Pattern;

public class Server extends Thread {

public static void main(String[] args) {
    (new Server()).run();
}

@Override
public void run() {

    try (ServerSocket serverSocket = new ServerSocket(9999)) {
        Socket socket;
        try {
            while ((socket = serverSocket.accept()) != null) {
                (new Handler(socket)).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    } catch (IOException e) {
        e.printStackTrace();
        return;
    }
}

public static class Handler extends Thread {
    public static final Pattern CONNECT_PATTERN = Pattern.compile("CONNECT (.+):(.+) HTTP/(1\\.[01])", Pattern.CASE_INSENSITIVE);
    public int port = 80;
    private final Socket clientSocket;

    public Handler(Socket clientSocket) {
        this.clientSocket = clientSocket;
    }

    @Override
    public void run() {
        try {

            byte[] buffer = new byte[4096];
            InputStream browserInputStream = clientSocket.getInputStream();

            int n = browserInputStream.read(buffer);

            String browserRequest = new String(buffer, 0, n);
            String[] requestLines = browserRequest.split("\r\n");

            if (requestLines[0].startsWith("CONNECT")) {
                //HTTPS TRAFFIC
                //Browser Request Received
                String[] connectRequest = requestLines[0].split(" ");
                String urlAndPort = connectRequest[1];
                String url = urlAndPort.split(":")[0];
                int port = Integer.parseInt(urlAndPort.split(":")[1]);

                OutputStreamWriter outputStreamWriter = new OutputStreamWriter(clientSocket.getOutputStream());

                final Socket forwardSocket;

                try {
                    forwardSocket = new Socket(url, port);
                } catch (IOException | NumberFormatException e) {
                    e.printStackTrace();
                    outputStreamWriter.write("HTTP/" + "1.1" + " 502 Bad Gateway\r\n");
                    outputStreamWriter.write("Proxy-agent: Simple/0.1\r\n");
                    outputStreamWriter.write("\r\n");
                    outputStreamWriter.flush();
                    return;
                }


                try {
                    //OK Response sent to browser
                    outputStreamWriter.write("HTTP/" + "1.1" + " 200 Connection established\r\n");
                    outputStreamWriter.write("Proxy-agent: Simple/0.1\r\n");
                    outputStreamWriter.write("\r\n");
                    outputStreamWriter.flush();

                    Thread remoteToClient = new Thread() {
                        @Override
                        public void run() {
                            forwardData(forwardSocket, clientSocket);
                        }
                    };

                    remoteToClient.start();

                    try {
                        forwardData(clientSocket, forwardSocket);
                    } finally {
                        try {
                            remoteToClient.join();
                        } catch (InterruptedException e) {
                            e.printStackTrace(); // TODO: implement catch
                        }
                    }
                } finally {
                    forwardSocket.close();
                }
            } else {
                //HTTP TRAFFIC
                int start = browserRequest.indexOf("Host: ") + 6;
                int end = browserRequest.indexOf('\n', start);
                String host = browserRequest.substring(start, end - 1);

                SocketChannel proxyToServerChannel = SocketChannel.open();
                Socket proxyToServerSocket = proxyToServerChannel.socket();
                //VpnServiceHelper.protect(proxyToServerSocket) //Protect the socket from VPNSERVICE

                InetSocketAddress serverAddress = new InetSocketAddress(host, port);
                proxyToServerChannel.configureBlocking(false);
                proxyToServerChannel.connect(serverAddress);

                while (!proxyToServerChannel.finishConnect());

                ByteBuffer buf = ByteBuffer.wrap(buffer);
                proxyToServerChannel.write(buf);

                try {
                    InputStream inputStream = proxyToServerSocket.getInputStream();
                    try {
                        OutputStream outputStream = clientSocket.getOutputStream();
                        try {

                            int read = 0;
                            do {

                                if (read == 0)
                                    try {
                                        Thread.sleep(500);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }

                                read = proxyToServerChannel.read(ByteBuffer.wrap(buffer));

                                if (read > 0) {
                                    clientSocket.getOutputStream().write(buffer);

                                    if (inputStream.available() < 1) {
                                        outputStream.flush();
                                    }
                                }
                            } while (read >= 0);

                        } finally {
                            if (!clientSocket.isOutputShutdown()) {
                                clientSocket.shutdownOutput();
                            }
                        }
                    } finally {
                        if (!proxyToServerSocket.isInputShutdown()) {
                            proxyToServerSocket.shutdownInput();
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }


        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static void forwardData(Socket inputSocket, Socket outputSocket) {
        try {
            InputStream inputStream = inputSocket.getInputStream();
            try {
                OutputStream outputStream = outputSocket.getOutputStream();
                try {
                    byte[] buffer = new byte[4096];
                    int read;
                    do {
                        read = inputStream.read(buffer);
                        if (read > 0) {
                            outputStream.write(buffer, 0, read);
                            if (inputStream.available() < 1) {
                                outputStream.flush();
                            }
                        }
                    } while (read >= 0);

                } finally {
                    if (!outputSocket.isOutputShutdown()) {
                        outputSocket.shutdownOutput();
                    }
                }
            } finally {
                if (!inputSocket.isInputShutdown()) {
                    inputSocket.shutdownInput();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
}

0 个答案:

没有答案