我正在尝试编写一段代码来实现代理服务器。但是,我无法将数据发送回客户端,因为响应如下所示。
响应显示正常响应,稍后会出现一些响应,表示URI太大。
HTTP/1.1 414 Request-URI Too Large
Date: Sun, 01 Sep 2013 14:52:20 GMT
Server: Apache/2.2.22 (Ubuntu)
Vary: Accept-Encoding
Content-Length: 325
Connection: close
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>414 Request-URI Too Large</title>
</head><body>
<h1>Request-URI Too Large</h1>
<p>The requested URL's length exceeds the capacity
limit for this server.<br />
</p>
<hr>
<address>Apache/2.2.22 (Ubuntu) Server at 127.0.1.1 Port 80</address>
</body></html>
代码如下。
package ownproxy;
/**
*
* @author mklrjv
*/
import java.net.*;
import java.io.*;
import java.nio.CharBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;
public class InterceptionProxy2 {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
boolean listening = true;
int port = 1234;
try {
serverSocket = new ServerSocket(port);
} catch (IOException e) {
System.out.println("Port Error");
System.exit(-1);
}
while (listening) {
new ProxyThread2(serverSocket.accept()).start();
}
serverSocket.close();
}
}
class ProxyThread2 extends Thread {
private Socket socket = null;
private static final int BUFFER_SIZE = 32768;
public ProxyThread2(Socket socket) {
super("ProxyThread2");
this.socket = socket;
}
public void run() {
PrintWriter outGoing = null;
try {
outGoing = new PrintWriter(socket.getOutputStream(), true);
BufferedReader inComing = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String incomingRequest;
String url = "";
String request = "";
String response = "";
//Take the incoming request
char[] buf = new char[1000000];
inComing.read(buf);
request = new String(buf);
//Create a new socket for connecting to destination server
Socket connSocket = new Socket("localhost", 80);
PrintWriter pOut = new PrintWriter(connSocket.getOutputStream(), true);
BufferedReader pIn = new BufferedReader(new InputStreamReader(connSocket.getInputStream()));
//Put data into the new socket(to the apache server) and receive its output
pOut.print(request);
pIn.read(buf);
response = new String(buf);
System.out.println(response);
//Put data back into the original client socket
outGoing.write(response);
} catch (IOException ex) {
Logger.getLogger(ProxyThread2.class.getName()).log(Level.SEVERE, null, ex);
} finally {
outGoing.close();
}
}
}
答案 0 :(得分:0)
导致414错误的原因并不明显。如果您没有在代理上使用Web浏览器但是手动发送GET请求(或其他一些非http请求),则代码中的错误(见下文)可能会导致GET请求中包含超过8196个字符,这是Apache的默认限制。
您应该更改代码,以便使用String(缓冲区,偏移量,长度)构造函数创建字符串,该构造函数使用读取的字节数,而不是完整缓冲区,如果请求和可能包含许多NULL值。回应很短。此外,您应该考虑将输出刷新回代理客户端。这是您的代码与这些更改
public void run() {
PrintWriter outGoing = null;
try {
outGoing = new PrintWriter(socket.getOutputStream(), true);
BufferedReader inComing = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String incomingRequest;
String url = "";
String request = "";
String response = "";
//Take the incoming request
char[] buf = new char[100000];
int bytesRead = inComing.read(buf);
request = new String(buf, 0, bytesRead);
//Create a new socket for connecting to destination server
Socket connSocket = new Socket("localhost", 10003);
PrintWriter pOut = new PrintWriter(connSocket.getOutputStream(), true);
//Reader for response from destination server
BufferedReader pIn = new BufferedReader(new InputStreamReader(connSocket.getInputStream()));
//Put data into the new socket(to the apache server) and receive its output
pOut.print(request);
pOut.flush();
bytesRead = pIn.read(buf);
if(bytesRead > 0) {
response = new String(buf, 0, bytesRead);
}
System.out.println(response);
//Put data back into the original client socket
outGoing.write(response);
} catch (IOException ex) {
Logger.getLogger(ProxyThread2.class.getName()).log(Level.SEVERE, null, ex);
} finally {
outGoing.close();
}
答案 1 :(得分:0)
你不能写这样的HTTP代理。你需要两个线程,每个方向一个,都只复制字节。原因是HTTP保持活着。你无法分辨请求者在哪里结束响应就是解析头文件,块等等。这一切都变得太难了。