protected void service ( HttpServletRequest pRequest , HttpServletResponse pResponse ) throws ServletException , IOException { // Sanity check configuration if ( remoteServer == null ) { log ( MESSAGE_REMOTE_SERVER_NOT_CONFIGURED ) ; pResponse . sendError ( HttpServletResponse . SC_INTERNAL_SERVER_ERROR , MESSAGE_REMOTE_SERVER_NOT_CONFIGURED ) ; return ; } HttpURLConnection remoteConnection = null ; try { // Recreate request URI for remote request String requestURI = createRemoteRequestURI ( pRequest ) ; URL remoteURL = new URL ( pRequest . getScheme ( ) , remoteServer , remotePort , requestURI ) ; // Get connection, with method from original request // NOTE: The actual connection is not done before we ask for streams... // NOTE: The HttpURLConnection is supposed to handle multiple // requests to the same server internally String method = pRequest . getMethod ( ) ; remoteConnection = ( HttpURLConnection ) remoteURL . openConnection ( ) ; remoteConnection . setRequestMethod ( method ) ; // Copy header fields copyHeadersFromClient ( pRequest , remoteConnection ) ; // Do proxy specifc stuff? // TODO: Read up the specs from RFC 2616 (HTTP) on proxy behaviour // TODO: RFC 2616 says "[a] proxy server MUST NOT establish an HTTP/1.1 // persistent connection with an HTTP/1.0 client" // Copy message body from client to remote server copyBodyFromClient ( pRequest , remoteConnection ) ; // Set response status code from remote server to client int responseCode = remoteConnection . getResponseCode ( ) ; pResponse . setStatus ( responseCode ) ; //System.out.println("Response is: " + responseCode + " " + remoteConnection.getResponseMessage()); // Copy header fields back copyHeadersToClient ( remoteConnection , pResponse ) ; // More proxy specific stuff? // Copy message body from remote server to client copyBodyToClient ( remoteConnection , pResponse ) ; } catch ( ConnectException e ) { // In case we could not connecto to the remote server log ( "Could not connect to remote server." , e ) ; pResponse . sendError ( HttpServletResponse . SC_BAD_GATEWAY , e . getMessage ( ) ) ; } finally { // Disconnect from server // TODO: Should we actually do this? if ( remoteConnection != null ) { remoteConnection . disconnect ( ) ; } } }
Services a single request . Supports HTTP and HTTPS .