我试图用Java编写HTTP代理。我的代理强制与另一个代理通信。就这样,从localhost端口接收GET请求,并抛出到外部代理。然后,获取外部代理响应并抛给客户端。
GET方法运作良好。但我不知道如何处理CONNECT方法。
我收到来自客户的CONNECT请求,抛出到外部代理,并从他那里收到200 Connection Established状态。这意味着外部代理已准备好将所有内容转发到请求的HOST。我也将200状态发送给了客户。但现在,我做了什么?
以下是代码:
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
//######################################################################
}
答案 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();
}