Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it L'avatar di MatCap83
    Registrato dal
    Jun 2005
    residenza
    Firenze
    Messaggi
    1,319

    [Java] Creazione HTTP proxy

    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();
    		}
    
    	}
    	
    }
    "Nessuno mi ha visto farlo, e non puoi provarlo in nessun modo!" (Bart Simpson)

    >>> www.ombresulweb.com <<<

  2. #2
    Quello che fa un proxy è semplicemente leggere la richiesta di un client (browser), inoltrarlo al server di destinazione, che leggi dall'header HTTP "Host", dominio (o IP) e porta (se non c'è va sulla 80), e ritrasferire i byte di risposta indietro così come sono...

    Non serve decodare il content della richiesta anche se è gzip tanto tu quello che devi fare e' semplicemente trasferire byte dal client al server di destinazione e viceversa.

    Ovviamente non devi collegarti dal browser direttamente digitando come url l'indirizzo del Proxy, ma devi configurare un proxy nelle impostazioni del browser oppure in quelle di connessione internet di windows.
    lolide
    Java Programmer

    Informati

  3. #3
    Utente di HTML.it L'avatar di MatCap83
    Registrato dal
    Jun 2005
    residenza
    Firenze
    Messaggi
    1,319
    Originariamente inviato da lolide
    Quello che fa un proxy è semplicemente leggere la richiesta di un client (browser), inoltrarlo al server di destinazione, che leggi dall'header HTTP "Host", dominio (o IP) e porta (se non c'è va sulla 80), e ritrasferire i byte di risposta indietro così come sono...

    Non serve decodare il content della richiesta anche se è gzip tanto tu quello che devi fare e' semplicemente trasferire byte dal client al server di destinazione e viceversa.

    Ovviamente non devi collegarti dal browser direttamente digitando come url l'indirizzo del Proxy, ma devi configurare un proxy nelle impostazioni del browser oppure in quelle di connessione internet di windows.
    Esatto, è quello che ho fatto io. Da browser ho configurato il proxy HTTP per puntare a localhost, e alla porta da me specificata. Ho controllato e le richieste passano correttamente dal proxy. Il problema è che i siti codificati con gzip non vengono visualizzati! I dati vengono trasferiti dal server destinazione al proxy al client con le classi BufferedOutputStream e BufferedInputStream, quindi come semplice sequenza di byte. Puntando però dal browser ad un sito che usa la codifica gzip (ad esempio www.libero.it), non viene visualizzata la pagina ma si apre invece una finestra "trasferimento file - file.gz - apri con..."?!? Ho provato con browser diversi, e non cambia niente... Sembra che il browser riceva qualcosa di diverso e non riesca a decodificarlo !
    "Nessuno mi ha visto farlo, e non puoi provarlo in nessun modo!" (Bart Simpson)

    >>> www.ombresulweb.com <<<

  4. #4
    Ma poi dal proxy al browser ripassi tutta la richiesta compresi gli Header HTTP settati dal server (in quel caso libero.it) oppure in qualche modo ripassi solo il Content della risposta impostando tu gli header?
    No perchè il server risponde con l'header Content-Encoding per dire al browser di decodare il content nell'encoding specificato.
    lolide
    Java Programmer

    Informati

  5. #5
    Utente di HTML.it L'avatar di MatCap83
    Registrato dal
    Jun 2005
    residenza
    Firenze
    Messaggi
    1,319
    Originariamente inviato da lolide
    Ma poi dal proxy al browser ripassi tutta la richiesta compresi gli Header HTTP settati dal server (in quel caso libero.it) oppure in qualche modo ripassi solo il Content della risposta impostando tu gli header?
    No perchè il server risponde con l'header Content-Encoding per dire al browser di decodare il content nell'encoding specificato.
    In teoria dal proxy al client passo la richiesta byte a byte interamente, quindi sia header che body. In particolare prendo lo stream input dal server e lo mando sull'output verso il client, tramite lettura di byte e non di character:

    proxyToClient= new BufferedOutputStream(clientSocket.getOutputStream( ), 1000);
    int inputFromInternet;

    System.out.println("Forwarding response to client...");

    proxyFromServer= new BufferedInputStream(connection.getInputStream(), 1000);

    while((inputFromInternet=proxyFromServer.read()) != -1)
    {
    proxyToClient.write(inputFromInternet); //proxy -> client
    }

    dove connection è un oggetto HttpURLConnection, ossia la connessione aperta dal proxy verso il server destinazione.
    Secondo me il problema sta nel fatto che dal programmino java viene ricreata una richiesta HttpURLConnection verso la destinazione, e in qualche modo viene fatto casino nelle richieste/risposte HTTP. Ora mi installo tamper data su firefox e analizzo bene gli header ! Boh!
    "Nessuno mi ha visto farlo, e non puoi provarlo in nessun modo!" (Bart Simpson)

    >>> www.ombresulweb.com <<<

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.