用Java编写CONNECT方法

时间:2015-12-02 11:35:58

标签: java http proxy connect

我试图用Java编写HTTP代理。我的代理强制与另一个代理通信。就这样,从localhost端口接收GET请求,并抛出到外部代理。然后,获取外部代理响应并抛给客户端。

GET方法运作良好。但我不知道如何处理CONNECT方法。

我收到来自客户的CONNECT请求,抛出到外部代理,并从他那里收到200 Connection Established状态。这意味着外部代理已准备好将所有内容转发到请求的HOST。我也将200状态发送给了客户。但现在,我做了什么?

enter image description here

以下是代码:

try {
    onLogReceived("<.> Thread inject: abrindo comunicação com " + this.hostDest + ":" + this.hostDestPort, LOG_LEVEL_INFO);
    socketHostDest = new Socket(this.hostDest, this.hostDestPort);

    try {
        inCliente = this.cliente.getInputStream();

        onLogReceived("<_> Thread inject: recebendo requisição cliente.", LOG_LEVEL_DEBUG);
        Requisicao reqCliente = getReqCliente(inCliente);
        reqCliente.setStrMacro(this.strMacro);

        outDestino = socketHostDest.getOutputStream();

        onLogReceived("<_> Thread inject: enviando requisição cliente.", LOG_LEVEL_DEBUG);
        writeStream(reqCliente.getStrRequisicao(), outDestino);

        inDestino = socketHostDest.getInputStream();

        onLogReceived("<_> Thread inject: recebendo resposta do destino.", LOG_LEVEL_DEBUG);
        String respostaDestino = getInputStreamStr(inDestino, TAM_BUFFER_RECEPCAO);
        String statusLine = respostaDestino.substring(0, respostaDestino.indexOf('\r'));

        onLogReceived("<.> Thread inject: Status line: " + statusLine, LOG_LEVEL_INFO);

        outCliente = this.cliente.getOutputStream();

        onLogReceived("<_> Thread inject: enviando resposta ao cliente.", LOG_LEVEL_DEBUG);
        writeStream(respostaDestino, outCliente);

        if (statusLine.contains(CONNECT_ESTABLISHED)) {

//######################################################################
//Its right here. I already receive the 200 code from the external proxy
//and already sent it to the client. Now we have opened the streams:
//
//outCliente: OutputStream to the client
//inCliente: InputStream to the client
//outDestino: OutputStream to the external proxy
//inCliente: OutputStream to the external proxy
//######################################################################

        }

1 个答案:

答案 0 :(得分:0)

感谢EJP。解决方案实际上只是在流代理和客户端之间传输字节。我的错是不是在单独的线程中这样做。代码看起来像这样:

public void run() {
    //Sender thread
    run(this.inCliente, this.outDestino, this.cliente, this.destino, this.tamBufferEnvio);    
    //Receiver thread
    run(this.inDestino, this.outCliente, this.destino, this.cliente, this.tamBufferRecepcao); 
}

private void run(final InputStream in, final OutputStream out, final Socket inSocket, final Socket outSocket, final int tamBuffer) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                byte []buffer = new byte[tamBuffer];
                int len = in.read(buffer);

                while (len != -1 && !inSocket.isOutputShutdown()) {
                    out.write(buffer, 0, len);
                    out.flush();
                    len = in.read(buffer);
                }

                if (len == -1 || inSocket.isOutputShutdown()) {
                    if (!isThread1Closed)
                        isThread1Closed = true;
                    else
                        isThread2Closed = true;
                    inSocket.shutdownInput();
                    outSocket.shutdownOutput();
                }
            } catch(IOException e) {
                onLogReceived("<#> Thread inject: erro na transfêrencia de dados. " + e.getMessage(), LOG_LEVEL_CRITICAL);
            } finally {
                if (isThread2Closed) {
                    try {
                        onLogReceived("<_> Thread inject: fechando comunicação.", LOG_LEVEL_DEBUG);
                        destino.close();
                        cliente.close();
                    } catch(IOException e) {
                        onLogReceived("<#> Thread inject: erro ao fechar comunicação. " + e.getMessage(), LOG_LEVEL_CRITICAL);
                    }
                }
            }
        }
    }).start();
}