Ciao a tutti, sto cercando di realizzare un semplice proxy HTTP in java, ma non riesco a venirne fuori. Il programma effettua questi passaggi:
1. intercetta le richieste HTTP inviate da un browser (con ServerSocket in ascolto)
2. esamina la HTTP request e "preleva" l'url della destinazione
3. crea una nuova HTTP request e si collega all'url destinazione
4. riceve la HTTP response dalla destinazione
5. inoltra la HTTP response al browser
In teoria funziona, ma nella pratica ho problemi a visualizzare alcuni siti, credo per via della codifica (encoding gz? utf-8?). La trasmissione della risposta da server a proxy e poi a client viene realizzata semplicemente leggendo/scrivendo byte, per evitare di andare a usare filtri con la possibilità di modificare/danneggiare i dati. Dunque non dovrebbe modificarsi niente se leggo/scrivo byte semplicemente?! Invece ho l'impressione che il browser abbia problemi a leggere la risposta e/o a decodificare i dati. Ho provato anche a decodificare i dati con GZIP*Stream, ma non riesco comunque a vedere tutte le pagine. Spero di aver esposto bene il problema!
Chiedo consiglio agli esperti...
Grazie!
Ecco il codice bozza:
codice:
import java.net.*;
import java.io.*;
import java.util.*;
import java.util.zip.*;
//architecture: client <-> proxy <-> Internet
public class HTTPProxy
{
/*** FIELDS ***/
private ServerSocket proxySocket= null;
private Socket clientSocket= null;
private BufferedReader CinputP= null; //input stream of proxy, client -> server
private BufferedOutputStream PoutputC= null; //output stream of proxy, server -> client
private BufferedInputStream IinputP= null; //input stream of proxy, Internet -> proxy
private HttpURLConnection connection= null;
private URL url= null; //URL requested from client
private int server_port;
private final int default_server_port= 9090;
/*** CONSTRUCTORS ***/
public HTTPProxy()
{
server_port= default_server_port;
}
public HTTPProxy(int port)
{
server_port= port;
}
/*** METHODS ***/
public void start()
{
try
{
proxySocket= new ServerSocket(server_port); //open 9090 port
System.out.println("Started server... on " + proxySocket.getLocalPort());
}catch(IOException ioe)
{
System.out.println("Attention: could not listen on port " + server_port + "!");
System.exit(-1);
}
while(true)
{
try
{
clientSocket= proxySocket.accept(); //accept incoming connections
CinputP= new BufferedReader(new InputStreamReader(clientSocket.getInputStream()), 1000);
String inputFromClient;
ArrayList<String> arrayHttpRequest= new ArrayList<String>(0);
//connectionToURL:
while(((inputFromClient= CinputP.readLine()) != null) && (!inputFromClient.trim().isEmpty()))
{
arrayHttpRequest.add(inputFromClient);
}
//start request of URL, proxy -> Internet
connect(arrayHttpRequest);
if(connection != null)
{
PoutputC= new BufferedOutputStream(clientSocket.getOutputStream(), 1000);
int inputFromInternet;
System.out.println("Forwarding response to client...");
System.out.println("encoding..." + connection.getContentEncoding());
IinputP= new BufferedInputStream(connection.getInputStream(), 1000);
while((inputFromInternet=IinputP.read()) != -1)
{
PoutputC.write(inputFromInternet); //proxy -> client
}
PoutputC.flush();
}else
{
System.exit(-1);
}
}catch(IOException ioe)
{
System.out.println("Attention: accept failed on port " + server_port + "!");
System.exit(-1);
}finally
{
try
{
PoutputC.close();
CinputP.close();
IinputP.close();
}catch(IOException ex)
{
ex.printStackTrace();
}
}
}
}
private void connect(ArrayList<String> request)
throws IOException, ProtocolException, MalformedURLException
{
String requestLine= request.get(0);
url= new URL(extractURL(requestLine)); //fetch request line
System.out.println("Connection... " + url.toString());
connection= (HttpURLConnection)url.openConnection();
connection.setRequestMethod(extractMethod(requestLine)); //check and set HTTP method
int endHeader;
String header, requestField;
for(int i= 1; i < request.size(); i++)
{//scan HTTP fields and create a new HTTP request
requestField= request.get(i);
endHeader= requestField.indexOf(":");
header= requestField.substring(0, endHeader);
connection.addRequestProperty(header, requestField.substring(endHeader+2));
}
connection.setDoOutput(true);
connection.connect();
System.out.println("Established connection.");
}
//extract URL from the request line (the first) of an HTTP request
private String extractURL(String requestLine)
{
int start= requestLine.indexOf(" ") + 1; //first empty space
int end= requestLine.lastIndexOf(" "); //last empty space
return requestLine.substring(start, end);
}
//check and return HTTP method of a HTTP request
private String extractMethod(String requestLine)
throws IOException
{
int endMethod= requestLine.indexOf(" ");
String method= requestLine.substring(0, endMethod);
if(method.equals("GET"))
{
return "GET";
}else
if(method.equals("HEAD"))
{
return "HEAD";
}else
if(method.equals("POST"))
{
return "POST";
}else
if(method.equals("PUT"))
{
return "PUT";
}else
if(method.equals("DELETE"))
{
return "DELETE";
}else
if(method.equals("TRACE"))
{
return "TRACE";
}else
if(method.equals("CONNECT"))
{
return "CONNECT";
}else
if(method.equals("OPTIONS"))
{
return "OPTIONS";
}else
{//wrong request
throw new IOException();
}
}
}