import java.io.*; import java.net.*; import java.util.Date; // wget -S public class ProxyServer3 { public static void main( String[] args ) { int port = 8126; // TO DO: read port from argv[1] ProxyServer3 theServer = new ProxyServer3( port ); } public ProxyServer3( int port ) { System.out.println( "Server started at " + new Date() ); try { // Create a server (listener) socket ServerSocket serverSocket = new ServerSocket( port, 5 ); // Note the second arg is 5, which is the backlog.... while ( true ) { // Listen for a connection request from a client System.out.println( "Blocking on accept()" ); Socket clientSocket = serverSocket.accept(); // BLOCK! System.out.println( "Client connection rcvd at " + new Date() ); // StringBuilder request = new StringBuilder(); InputStream stream = clientSocket.getInputStream(); // ADD BUFFERED READER: BufferedReader in = new BufferedReader( new InputStreamReader( stream ) ); String request = in.readLine(); System.out.println( "Request-Line is: " + request ); // Isolate the hostname from within the Request-Line: // GET http://www.cs.rpi.edu/index.html HTTP/1.1 // ^ ^ ^ // a b c int a = request.indexOf( "://" ) + 3; int b = request.indexOf( "/", a ); int c = request.indexOf( " ", b ); String requestedHost = request.substring( a, b ); String newRequestLine = "GET " + request.substring( b, c ) + " HTTP/1.1"; StringBuilder newRequestHeaders = new StringBuilder(); newRequestHeaders.append( "Host: " ); newRequestHeaders.append( requestedHost ); newRequestHeaders.append( "\r\n" ); System.out.println( newRequestLine + "\r\n" + newRequestHeaders.toString() + "\r\n" ); // e.g. // GET /index.html HTTP/1.1 // Host: www.cs.rpi.edu String header; while ( ( header = in.readLine() ) != null ) { System.out.println( "RCVD: " + header ); //header = header.trim(); if ( header.length() == 0 ) break; if ( header.startsWith( "User-Agent:" ) || header.startsWith( "Accept" ) ) { newRequestHeaders.append( header + "\r\n" ); } } System.out.println(); System.out.println(); newRequestHeaders.append( "\r\n" ); String newRequest = newRequestLine + "\r\n" + newRequestHeaders.toString() + "\r\n"; System.out.println( newRequest ); // Create a socket (socket() in C) and attempt to connect // to a server at a specific port number (connect() in C) Socket toWebServerSocket = new Socket( requestedHost, 80 ); OutputStream toWebServerStream = toWebServerSocket.getOutputStream(); toWebServerStream.write( newRequest.getBytes() ); toWebServerStream.flush(); InputStream fromWebServerStream = toWebServerSocket.getInputStream(); BufferedReader input = new BufferedReader( new InputStreamReader( fromWebServerStream ) ); String responseLine = input.readLine(); System.out.println( "Response-Line is: " + responseLine ); StringBuilder response = new StringBuilder(); response.append( responseLine ); response.append( "\r\n" ); String header2; int contentLength = 0; while ( ( header2 = input.readLine() ) != null ) { System.out.println( "RCVD: " + header2 ); if ( header2.length() == 0 ) break; if ( header2.startsWith( "Content-Length:" ) ) { String h = header2.substring( 16 ); contentLength = Integer.parseInt( h ); System.out.println( "content length is " + contentLength ); } if ( header2.equals( "Transfer-Encoding: chunked" ) ) { contentLength = 50000; } response.append( header2 ); response.append( "\r\n" ); } response.append( "Connection: close\r\n" ); response.append( "\r\n" ); byte[] rawData = new byte[contentLength]; for ( int q = 0 ; q < contentLength ; q++ ) { rawData[q] = (byte)input.read(); } response.append( new String( rawData ) ); System.out.println( response.toString() ); OutputStream ostream = clientSocket.getOutputStream(); ostream.write( response.toString().getBytes() ); ostream.flush(); System.out.println( "Sent response" ); } } catch ( IOException ex ) { System.err.println( "ERROR: " + ex ); } } }