简体   繁体   English

适用于Android的处理SSL的代理服务器

[英]Proxy Server for Android handling SSL

I'm writing my own proxy server. 我正在编写自己的代理服务器。 I have simplest implementation. 我有最简单的实现。 First code fragment is to set server listening on port 8080 (on which requests will be redirected by WiFi settings): 第一个代码片段是设置服务器在端口8080上侦听(请求将通过WiFi设置重定向):

public class MyProxyServer {

private ServerSocket proxyServer;

public void init() throws Exception {
    proxyServer = new ServerSocket(8080);

    new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                try {
                    Socket proxySocket = proxyServer.accept();
                    ProxyConnectionHandler proxyConnectionHandler = new ProxyConnectionHandler(proxySocket);
                    new Thread(proxyConnectionHandler).start();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }).start();
}

} }

Second is passing request and response data through sockets: 其次是通过套接字传递请求和响应数据:

public class ProxyConnectionHandler implements Runnable {

private static final int BUFFER_SIZE = 8192;

Socket mProxySocket;
Socket mOutsideSocket;

public ProxyConnectionHandler(Socket proxySocket) {
    mProxySocket = proxySocket;
}

@Override
public void run() {
    try {
        long startTimestamp = System.currentTimeMillis();

        InputStream proxyInputStream = mProxySocket.getInputStream();


        byte[] bytes = new byte[BUFFER_SIZE];
        int bytesRead = proxyInputStream.read(bytes, 0, BUFFER_SIZE);
        String request = new String(bytes);

        Log.d("ACHTUNG", "Request: " + request);

        String host = extractHost(request);

        int port = request.startsWith("CONNECT") ? 443 : 80;
        mOutsideSocket = new Socket(host, port);
        OutputStream outsideOutputStream = mOutsideSocket.getOutputStream();
        outsideOutputStream.write(bytes, 0, bytesRead);
        outsideOutputStream.flush();

        InputStream outsideSocketInputStream = mOutsideSocket.getInputStream();
        OutputStream proxyOutputStream = mProxySocket.getOutputStream();
        byte[] responseArray = new byte[BUFFER_SIZE];

        do
        {
            bytesRead = outsideSocketInputStream.read(responseArray, 0, BUFFER_SIZE);
            if (bytesRead > 0)
            {
                proxyOutputStream.write(responseArray, 0, bytesRead);
                String response = new String(bytes, 0, bytesRead);
                Log.d("ACHTUNG", "Response: " + response);
            }
        } while (bytesRead > 0);

        proxyOutputStream.flush();
        mOutsideSocket.close();
        mProxySocket.close();

        Log.d("ACHTUNG", "Cycle: " + (System.currentTimeMillis() - startTimestamp));

    } catch (Exception e) {
        e.printStackTrace();
    }
}

private String extractHost(String request) {
    int hStart = request.indexOf("Host: ") + 6;
    int hEnd = request.indexOf('\n', hStart);
    return request.substring(hStart, hEnd - 1);
}

} }

When I enter the browser it's working for HTTP pages but not for HTTPS. 当我进入浏览器时,它适用于HTTP页面,但不适用于HTTPS。 There is something more to handle SSL. 还有更多可以处理SSL的内容。 I don't want to read SSL packages, I just want to pass them through. 我不想阅读SSL软件包,我只想通过它们。 How to do it ? 怎么做 ?

I've found solution. 我找到了解决方案。

In case of SSL requests from client are modified to HTTP "CONNECT" method. 如果来自客户端的SSL请求被修改为HTTP“连接”方法。 However that request mustn't go to outside server.The proxy server must respond to client with: 但是,该请求不能发送到外部服务器。代理服务器必须使用以下命令响应客户端:

"HTTP/1.1 200 Connection established\r\n\r\n"

Next step is to allow bidirectional socket connection between client and server. 下一步是允许客户端和服务器之间的双向套接字连接。 It should look like this: 它看起来应该像这样:

public class Https443RequestHandler implements RequestHandler {

    private static final int BUFFER_SIZE = 8192;
    private static final String CRLF = "\r\n";

    Socket mProxySocket;
    Socket mOutsideSocket;

    public Https443RequestHandler(Socket proxySocket) {
        this.mProxySocket = proxySocket;
    }

    @Override
    public void handle(String request) throws Exception {
        byte[] bytes = request.getBytes();
        int bytesRead = bytes.length;

        String host = extractHost(request);
        int port = 443;

        mOutsideSocket = new Socket();
        mOutsideSocket.setKeepAlive(true);
        mOutsideSocket.connect(new InetSocketAddress(host, port));

        OutputStream proxyOutputStream = mProxySocket.getOutputStream();
        proxyOutputStream.write(("HTTP/1.1 200 Connection established" + CRLF + CRLF).getBytes());
        proxyOutputStream.flush();

        DirectionalConnectionHandler client = new DirectionalConnectionHandler(mProxySocket, mOutsideSocket);
        client.start();
        DirectionalConnectionHandler server = new DirectionalConnectionHandler(mOutsideSocket, mProxySocket);
        server.start();

        client.join();
        server.join();

        mOutsideSocket.close();
        mProxySocket.close();
    }

    private String extractHost(String request) {
        int hStart = request.indexOf("Host: ") + 6;
        int hEnd = request.indexOf('\n', hStart);
        return request.substring(hStart, hEnd - 1);
    }
}

.

public class DirectionalConnectionHandler extends Thread
{
    private final InputStream in;
    private final OutputStream out;

    DirectionalConnectionHandler(final Socket sin, final Socket sout) throws IOException
    {
        in = sin.getInputStream();
        out = sout.getOutputStream();
    }

    @Override
    public void run()
    {
        final byte[] buf = new byte[4096];
        int count;

        try
    {
        while ((count = in.read(buf, 0, buf.length)) != -1)
        {
            String stream = new String(buf);
            out.write(buf, 0, count);
        }
        out.flush();
    }
    catch (final IOException e)
    {
        // Just swallow as we can't recover from this
    }
}

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM