Open In App

Setting Up Proxy Connection to a System in Java

Last Updated : 28 Apr, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

In today’s networking environments, categorically corporate ones, application developers have to deal with proxies virtually as often as system administrators. In some cases the application should utilize the system default settings, in other cases, it will be additive to have very tight control over what goes through which proxy, and, somewhere in the middle, most applications will be ecstatic to delegate the decision to their users by providing them with a GUI to set the proxy settings, as is the case in most browsers.

Proxy servers act as interfaces between client applications and other servers. In an enterprise setting, we often use them to help provide control over the content that users consume, usually across network boundaries.

Approaches:

We will figure out two ways by which we can connect across proxy servers in java which are as follows:

  1. Legacy approach that is JVM-wide and configured with system properties.
  2. Using Proxy class which provides more control by permitting configuration on the basis of each connection.

Method 1: Using a Global Setting

Java exhibits a set of system properties that can be used to set up the JVM-wide behavior. This “universal” approach is often the simplest to implement if it is appropriate for the use case. We can set the required properties from the command line during the invocation of the JVM. Alternatively, we can also define them using System.setProperty() at runtime. Here’s how to define them using the command line as shown below:

2.1. Set via Command Line Arguments

We can define proxies at the command line bypassing the parameters as system properties:

java -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8080 com.geeksforgeeks.networking.proxies.CommandLineProxyDemo

When starting a process that way, we can just use openConnection() on the URL with no extra work:

URL url = new URL(RESOURCE_URL);

URLConnection con = url.openConnection();

2.3 Set Proxy Using the System.setProperty() method

If there are problems when using the command line, there is another way to do this using the System.setProperty() method. To set up a proxy.

System.setProperty(“http.proxyHost”, “127.0.0.1”);  

System.setProperty(“http.proxyPort”, “8080”);  

URL url = new URL(RESOURCE_URL);  

URLConnection con = url.openConnection();  

// …  

If we then manually disable the relevant system properties, then the proxy will not be used anymore:

System.setProperty(“http.proxyHost”, null); 

Now with this there do comes limitations of global configuration which is as described further.

  • The global configuration approach is the easiest way to define the proxy, but there are certain limitations to this approach.
  • This approach provides the implementation on the JVM-wide, so the settings define for a particular protocol are active for the life of the JVM or until we unset them manually.

Note: To get over this limitation, it may be attractive to flip the settings on and off, if needed. But, it would be necessary to ensure the measures to protect against concurrency issues in a multi-threaded program.

So, as an alternative, the Proxy API is more efficient and provides more control over proxy configuration. As an alternative, the Proxy API provides more granular control over proxy configuration. This gives out birth to another approach that via Proxy API

Method 2: Using the Proxy API

The Proxy class gives us a flexible way to configure proxies on a per-connection basis. If there are any existing JVM-wide proxy settings, connection-based proxy settings using the Proxy class will override them. Here are three types of proxies that we can define by Proxy Type:

  1. HTTP  is a proxy using the HTTP protocol
  2. SOCKS is a proxy using the SOCKS protocol
  3. DIRECT is an explicitly configured direct connection without a proxy

(A) Using an HTTP Proxy

To use an HTTP proxy, we first wrap a SocketAddress instance with a Proxy and type of Proxy.Type.HTTP. Next, we simply pass the Proxy instance to URLConnection.openConnection():

URL weburl = new URL(URL_STRING);

Proxy webProxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(“127.0.0.1”, 8080));

HttpURLConnection webProxyConnection = (HttpURLConnection) weburl.openConnection(webProxy);

Now, we’ll connect to URL_STRING but then route that connection through a proxy server hosted at 127.0.0.1:8080.

(B) Using a DIRECT Proxy

We may have a requirement to connect directly to a host. In this case, we can explicitly bypass a proxy that may be configured globally by using the static Proxy.NO_PROXY instance. Under the covers, the API constructs a new instance of Proxy for us, using Proxy.Type.DIRECT as the type:

HttpURLConnection directConnection = (HttpURLConnection) weburl.openConnection(Proxy.NO_PROXY); 

(C) Using a SOCKS Proxy

The Socks proxy works similarly to the HTTP variant while dealing with URLConnection. In Socks proxy, first, we wrap a SocketAddress instance with a Proxy using the Proxy.Type.SOCKS type. After that, the Proxy instance is passed to URLConnection.openConnection.

Proxy socksProxy  = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(“127.0.0.1”, 1080));

HttpURLConnection socksConnection = (HttpURLConnection) weburl.openConnection(socksProxy);

It’s also possible to use a SOCKS proxy when connecting to a TCP socket. First, we use the Proxy instance to construct a Socket. Afterward, we pass the destination SocketAddress instance to Socket.connect() as follows:

Socket proxySocket = new Socket(socksProxy);

InetSocketAddress socketHost = new InetSocketAddress(SOCKET_SERVER_HOST, SOCKET_SERVER_PORT);

proxySocket.connect(socketHost);

Example:

Java




// Java Program to Create a Simple Proxy Server
  
// Importing input output classes
import java.io.*;
// Importing
import java.net.*;
  
public class SimpleProxyServer {
    public static void main(String[] args)
        throws IOException
    {
        try {
            String host = "your Proxy Server";
            int remoteport = 100;
            int localport = 111;
            // Print a start-up message
            System.out.println("Starting proxy for " + host
                               + ":" + remoteport
                               + " on port " + localport);
            // And start running the server
            runServer(host, remoteport,
                      localport); // never returns
        }
        catch (Exception e) {
            System.err.println(e);
        }
    }
  
    /**
     * runs a single-threaded proxy server on
     * the specified local port. It never returns.
     */
    public static void
    runServer(String host, int remoteport, int localport)
        throws IOException
    {
        // Create a ServerSocket to listen for connections
        // with
        ServerSocket ss = new ServerSocket(localport);
  
        final byte[] request = new byte[1024];
        byte[] reply = new byte[4096];
  
        while (true) {
            Socket client = null, server = null;
            try {
                // Wait for a connection on the local port
                client = ss.accept();
  
                final InputStream streamFromClient
                    = client.getInputStream();
                final OutputStream streamToClient
                    = client.getOutputStream();
  
                // Make a connection to the real server.
                // If we cannot connect to the server, send
                // an error to the client, disconnect, and
                // continue waiting for connections.
                try {
                    server = new Socket(host, remoteport);
                }
                catch (IOException e) {
                    PrintWriter out
                        = new PrintWriter(streamToClient);
                    out.print(
                        "Proxy server cannot connect to "
                        + host + ":" + remoteport + ":\n"
                        + e + "\n");
                    out.flush();
                    client.close();
                    continue;
                }
  
                // Get server streams.
                final InputStream streamFromServer
                    = server.getInputStream();
                final OutputStream streamToServer
                    = server.getOutputStream();
  
                // a thread to read the client's requests
                // and pass them to the server. A separate
                // thread for asynchronous.
                Thread t = new Thread() {
                    public void run()
                    {
                        int bytesRead;
                        try {
                            while ((bytesRead
                                    = streamFromClient.read(
                                        request))
                                   != -1) {
                                streamToServer.write(
                                    request, 0, bytesRead);
                                streamToServer.flush();
                            }
                        }
                        catch (IOException e) {
                        }
  
                        // the client closed the connection
                        // to us, so close our connection to
                        // the server.
                        try {
                            streamToServer.close();
                        }
                        catch (IOException e) {
                        }
                    }
                };
  
                // Start the client-to-server request thread
                // running
                t.start();
  
                // Read the server's responses
                // and pass them back to the client.
                int bytesRead;
                try {
                    while ((bytesRead
                            = streamFromServer.read(reply))
                           != -1) {
                        streamToClient.write(reply, 0,
                                             bytesRead);
                        streamToClient.flush();
                    }
                }
                catch (IOException e) {
                }
  
                // The server closed its connection to us,
                // so we close our connection to our client.
                streamToClient.close();
            }
            catch (IOException e) {
                System.err.println(e);
            }
            finally {
                try {
                    if (server != null)
                        server.close();
                    if (client != null)
                        client.close();
                }
                catch (IOException e) {
                }
            }
        }
    }
}


Output:

Conclusion: As per the output we peek out how to work with proxy servers in core Java. First, we looked at the older, more global style of connecting through proxy servers using system properties. Then, we saw how to use the Proxy class, which provides fine-grained control when connecting through proxy servers.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads