【发布时间】:2015-12-11 16:41:24
【问题描述】:
我正在使用 apache 的 HttpCore 实现代理。
这是我的 HttpRequestHandler,它基于反向代理示例,来自 apache link:
static class ProxyHandler implements HttpRequestHandler {
private final HttpHost target;
private final HttpProcessor httpproc;
private final HttpRequestExecutor httpexecutor;
private final ConnectionReuseStrategy connStrategy;
private SocketFactory sf;
public ProxyHandler(
final HttpHost target,
final HttpProcessor httpproc,
final HttpRequestExecutor httpexecutor,
SocketFactory sf) {
super();
this.target = target;
this.httpproc = httpproc;
this.httpexecutor = httpexecutor;
this.sf = sf;
this.connStrategy = DefaultConnectionReuseStrategy.INSTANCE;
}
public void handle(
final HttpRequest request,
final HttpResponse response,
final HttpContext context) throws HttpException, IOException {
final int bufsize = 8 * 1024;
URI uri = null;
try {
uri = new URI(request.getRequestLine().getUri());
} catch (URISyntaxException e) {
e.printStackTrace();
return;
}
String domain = uri.getHost();
HttpHost host = new HttpHost(domain, 80);
System.out.println("host "+domain);
DefaultBHttpClientConnection outconn = (DefaultBHttpClientConnection) context.getAttribute(HTTP_OUT_CONN);
final Socket outsocket = sf.createSocket(host.getHostName(), this.target.getPort());
outconn = new DefaultBHttpClientConnection(bufsize);
outconn.bind(outsocket);
System.out.println("My Outgoing connection to " + outsocket.getInetAddress());
context.setAttribute(HTTP_OUT_CONN, outconn);
final HttpClientConnection conn = (HttpClientConnection) context.getAttribute(
HTTP_OUT_CONN);
context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn);
context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, this.target);
System.out.println(">> Request URI: " + request.getRequestLine().getUri());
// Remove hop-by-hop headers
request.removeHeaders(HTTP.CONTENT_LEN);
request.removeHeaders(HTTP.TRANSFER_ENCODING);
request.removeHeaders(HTTP.CONN_DIRECTIVE);
request.removeHeaders("Keep-Alive");
request.removeHeaders("Proxy-Authenticate");
request.removeHeaders("TE");
request.removeHeaders("Trailers");
request.removeHeaders("Upgrade");
this.httpexecutor.preProcess(request, this.httpproc, context);
final HttpResponse targetResponse = this.httpexecutor.execute(request, conn, context);
this.httpexecutor.postProcess(response, this.httpproc, context);
// Remove hop-by-hop headers
targetResponse.removeHeaders(HTTP.CONTENT_LEN);
targetResponse.removeHeaders(HTTP.TRANSFER_ENCODING);
targetResponse.removeHeaders(HTTP.CONN_DIRECTIVE);
targetResponse.removeHeaders("Keep-Alive");
targetResponse.removeHeaders("TE");
targetResponse.removeHeaders("Trailers");
targetResponse.removeHeaders("Upgrade");
response.setStatusLine(targetResponse.getStatusLine());
response.setHeaders(targetResponse.getAllHeaders());
response.setEntity(targetResponse.getEntity());
System.out.println("<< Response: " + response.getStatusLine());
final boolean keepalive = this.connStrategy.keepAlive(response, context);
context.setAttribute(HTTP_CONN_KEEPALIVE, new Boolean(keepalive));
outsocket.close();
}
}
我已经更改了处理函数并在其中创建,
DefaultBHttpClientConnection outconn 基于请求 URI 中的主机。
如您所见,我使用 SocketFactory 创建了一个新套接字 (outsocket)。
问题我不知道如何关闭套接字。
我尝试在 handle() 结束时关闭它,但随后我会开始接收
I/O 错误:套接字关闭
代理停止工作。
调用 httpservice.handleRequest() 的线程与链接中示例中的线程相同(如果需要,我可以发布它,我没有导致它在问题中占用空间)。
【问题讨论】: