我已经尝试了一些不同的方法来使我的自定义代理工作,而我迄今为止唯一能够通过使用Apache的HttpClient。但是,为了便于了解,我想知道为什么我在下面使用自己的代理句柄实现时出现问题:
public void processProxyRequest (Socket client, String request) throws Exception {
if ( !request.equals("") ) {
String[] requestHeaders = request.split("\\r\\n");
Pattern p = Pattern.compile("([A-Z]*)\\s*([^:\\/]*):\\/\\/([^\\s]*)\\s*(?:HTTP.*)");
Matcher m = p.matcher(requestHeaders[0]);
if ( m.matches() ) {
String method = m.group(1).toUpperCase();
String proto = m.group(2).toLowerCase();
String[] requestInfo = m.group(3).split("\\/", 2);
String host = requestInfo[0];
host = ( host.split("\\.").length < 3 ) ? "www." + host : host;
String page = "/";
if ( requestInfo.length == 2 && !requestInfo[1].equals("") ) {
page += requestInfo[1];
}
int remotePort = 80;
if ( proto.equals("https") ) {
remotePort = 443;
}
else if ( proto.equals("ftp") ) {
remotePort = 21;
}
this.sendAndReceive(client, request, host, remotePort);
}
}
}
public void sendAndReceive (Socket client, String request, String host, int port) throws Exception {
Socket target = new Socket(host, port);
System.out.println("Connected to server");
ByteArrayInputStream inStream = new ByteArrayInputStream(request.getBytes());
this.inToOut(inStream, target.getOutputStream());
System.out.println("Sent");
this.inToOut(target.getInputStream(), client.getOutputStream());
System.out.println("Received");
target.close();
}
public void inToOut (InputStream input, OutputStream output) throws IOException {
byte[] buffer = new byte[1024]; // Adjust if you want
int bytesRead;
System.out.println("reading");
while ((bytesRead = input.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
}
简而言之(并且忽略了我的请求头解析缺陷),上面的代码编译并运行,但是,inToOut()
方法似乎有点挣扎并在input.read()期间锁定,而我我不太清楚为什么。我确实知道我传入的原始套接字是有效的并且没有错误地打开。此外,inToOut()函数中的System.out
会打印“阅读”,但永远不会超过read()
部分。
感谢您的任何建议!
答案 0 :(得分:1)
这无法编写代理。在HTTP的情况下,您只需要处理第一行,它会告诉您目标主机。其他所有内容只是来回复制字节,需要进行一些细微的改进,例如正确报告上游连接错误并正确处理关闭。 FTP的情况比较棘手,应该完全单独处理,但是一旦你通过连接阶段,它只是复制字节。你理解协议的努力越少越简单,越好。
答案 1 :(得分:0)
在你的sendAndReceive函数中,也许尝试使用DataInputStream和DataOutputStream
public void sendAndReceive (Socket client, String request, String host, int port) throws Exception {
Socket target = new Socket(host, port);
System.out.println("Connected to server");
this.inToOut(new DataInputStream(client.getInputStream()), new DataOutputStream(target.getOutputStream()));
System.out.println("Sent");
this.inToOut(new DataInputStream(target.getInputStream()), new DataOutputStream(client.getOutputStream()));
System.out.println("Received");
target.close();
}
问题似乎不在inToOut函数中 - 我已经尝试使用inToOut()并且它工作正常(它实际上帮助我解决了我遇到类似问题的问题 - 谢谢)