I am trying to write a simple web proxy in java which accepts both GET and POST requests. I wrote the following code:
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 clientSocket = null;
private Socket serverSocket = null;
public ProxyThread2(Socket socket) {
super("ProxyThread2");
this.clientSocket = socket;
}
public void run() {
//Stream to put data to the browser
PrintWriter outGoing = null;
try {
outGoing = new PrintWriter(clientSocket.getOutputStream(), true);
//Stream to get data from the browser
BufferedReader inComing = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String incomingRequest;
String url = "";
String request = "";
String response = "";
//Take the incoming request
char[] buf = new char[8196]; //8196 is the default max size for GET requests in Apache
int bytesRead = inComing.read(buf); //BytesRead need to be calculated if the char buffer contains too many values
request = new String(buf, 0, bytesRead);
System.out.println("Request");
System.out.println(request);
//Create a new socket for connecting to destination server
serverSocket = new Socket("localhost", 80);
PrintWriter pOut = new PrintWriter(serverSocket.getOutputStream(), true);
//Reader for response from destination server
BufferedReader pIn = new BufferedReader(new InputStreamReader(serverSocket.getInputStream()));
//Put data into the new socket(to the apache server) and receive its output
pOut.print(request);
pOut.flush();
bytesRead = pIn.read(buf);
//Check if data is read
if (bytesRead > 0) {
response = new String(buf, 0, bytesRead);
}
System.out.println("Response");
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();
}
}
}
The system properly prints the request and response as output, but, the proxy does not provide the reply back to the browser. Is there anything wrong with the outGoing stream definition? Or should I create a new socket to send data back to the browser?
You don't need to create another instance of java.net.ServerSocket. Because you must connect to port 80, you are a client.
Socket socket = new Socket("localhost", 80);
e.g.:
class ProxyThread extends Thread {
private final Socket clientSocket;
public ProxyThread(Socket socket) {
this.clientSocket = socket;
}
public void run() {
try {
// Read request
InputStream incommingIS = clientSocket.getInputStream();
byte[] b = new byte[8196];
int len = incommingIS.read(b);
if (len > 0) {
System.out.println("REQUEST"
+ System.getProperty("line.separator") + "-------");
System.out.println(new String(b, 0, len));
// Write request
Socket socket = new Socket("localhost", 80);
OutputStream outgoingOS = socket.getOutputStream();
outgoingOS.write(b, 0, len);
// Copy response
OutputStream incommingOS = clientSocket.getOutputStream();
InputStream outgoingIS = socket.getInputStream();
for (int length; (length = outgoingIS.read(b)) != -1;) {
incommingOS.write(b, 0, length);
}
incommingOS.close();
outgoingIS.close();
outgoingOS.close();
incommingIS.close();
socket.close();
} else {
incommingIS.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Your Code working for simple text files or html. There is only one problem, only the HTTP header are text data everything in the body of the HTTP message could be simple byte data like images.
You shouldn't use the PrintWriter and/or Strings to convert the response. You should simply forward the byte buffer you will get from the Server. Just convert the byte buffer only if you want to show yourself the HTTP message.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With