En los entornos de red de hoy en día, categóricamente corporativos, los desarrolladores de aplicaciones tienen que tratar con proxies prácticamente con la misma frecuencia que los administradores de sistemas. En algunos casos, la aplicación debe utilizar la configuración predeterminada del sistema, en otros casos, será adicional tener un control muy estricto sobre qué pasa a través de qué proxy y, en algún punto intermedio, la mayoría de las aplicaciones estarán encantadas de delegar la decisión a su usuarios proporcionándoles una GUI para establecer la configuración del proxy, como es el caso en la mayoría de los navegadores.
Los servidores proxy actúan como interfaces entre las aplicaciones cliente y otros servidores. En un entorno empresarial, a menudo los usamos para ayudar a proporcionar control sobre el contenido que consumen los usuarios, generalmente a través de los límites de la red.
Enfoques:
Descubriremos dos formas en las que podemos conectarnos a través de servidores proxy en Java, que son las siguientes:
- Enfoque heredado que abarca toda la JVM y está configurado con propiedades del sistema.
- Uso de la clase Proxy que proporciona más control al permitir la configuración en función de cada conexión.
Método 1: usar una configuración global
Java exhibe un conjunto de propiedades del sistema que se pueden usar para configurar el comportamiento de toda la JVM. Este enfoque «universal» suele ser el más simple de implementar si es apropiado para el caso de uso. Podemos establecer las propiedades requeridas desde la línea de comando durante la invocación de la JVM. Alternativamente, también podemos definirlos usando System.setProperty() en tiempo de ejecución. Aquí se explica cómo definirlos usando la línea de comando como se muestra a continuación:
2.1. Establecer a través de argumentos de línea de comandos
Podemos definir proxies en la línea de comando sin pasar por los parámetros como propiedades del sistema:
java -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8080 com.geeksforgeeks.networking.proxies.CommandLineProxyDemo
Al iniciar un proceso de esa manera, podemos usar openConnection() en la URL sin trabajo adicional:
URL url = nueva URL (URL_RECURSO);
URLConnection con = url.openConnection();
2.3 Establecer proxy usando el método System.setProperty()
Si hay problemas al usar la línea de comando, hay otra forma de hacerlo usando el método System.setProperty(). Para configurar un proxy.
System.setProperty(“http.proxyHost”, “127.0.0.1”);
System.setProperty(“http.proxyPort”, “8080”);
URL url = nueva URL (URL_RECURSO);
URLConnection con = url.openConnection();
// …
Si luego deshabilitamos manualmente las propiedades relevantes del sistema, entonces el proxy ya no se usará:
System.setProperty(“http.proxyHost”, nulo);
Ahora, con esto, vienen las limitaciones de la configuración global, que se describe más adelante.
- El enfoque de configuración global es la forma más fácil de definir el proxy, pero existen ciertas limitaciones para este enfoque.
- Este enfoque proporciona la implementación en toda la JVM, por lo que la configuración definida para un protocolo en particular está activa durante la vida útil de la JVM o hasta que la desactivemos manualmente.
Nota: para superar esta limitación, puede ser atractivo activar y desactivar la configuración, si es necesario. Sin embargo, sería necesario garantizar las medidas de protección contra problemas de concurrencia en un programa de subprocesos múltiples.
Entonces, como alternativa, la API de proxy es más eficiente y brinda más control sobre la configuración del proxy. Como alternativa, la API de proxy proporciona un control más granular sobre la configuración del proxy. Esto da a luz a otro enfoque que a través de la API Proxy
Método 2: usar la API de proxy
La clase Proxy nos brinda una forma flexible de configurar proxies por conexión. Si hay alguna configuración de proxy existente en toda la JVM, la configuración de proxy basada en la conexión que utiliza la clase Proxy la anulará. Aquí hay tres tipos de proxies que podemos definir por Tipo de Proxy:
- HTTP es un proxy que utiliza el protocolo HTTP
- SOCKS es un proxy que utiliza el protocolo SOCKS
- DIRECTO es una conexión directa configurada explícitamente sin un proxy
(A) Uso de un proxy HTTP
Para usar un proxy HTTP, primero envolvemos una instancia de SocketAddress con un Proxy y el tipo de Proxy.Type.HTTP. A continuación, simplemente pasamos la instancia de Proxy a URLConnection.openConnection():
URL weburl = nueva URL (URL_STRING);
Proxy webProxy = nuevo Proxy(Proxy.Type.HTTP, nueva InetSocketAddress(“127.0.0.1”, 8080));
HttpURLConnection webProxyConnection = (HttpURLConnection) weburl.openConnection(webProxy);
Ahora, nos conectaremos a URL_STRING pero luego enrutaremos esa conexión a través de un servidor proxy alojado en 127.0.0.1:8080.
(B) Uso de un proxy DIRECTO
Es posible que tengamos un requisito para conectarnos directamente a un host. En este caso, podemos omitir explícitamente un proxy que puede configurarse globalmente mediante el uso de la instancia estática Proxy.NO_PROXY. Debajo de las cubiertas, la API construye una nueva instancia de Proxy para nosotros, utilizando Proxy.Type.DIRECT como el tipo:
HttpURLConnection directConnection = (HttpURLConnection) weburl.openConnection(Proxy.NO_PROXY);
(C) Uso de un proxy SOCKS
El proxy Socks funciona de manera similar a la variante HTTP cuando se trata de URLConnection. En el proxy de Socks, primero, envolvemos una instancia de SocketAddress con un Proxy usando el tipo Proxy.Type.SOCKS. Después de eso, la instancia de Proxy se pasa a URLConnection.openConnection.
Proxy socksProxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(“127.0.0.1”, 1080));
HttpURLConnection calcetinesConnection = (HttpURLConnection) weburl.openConnection(socksProxy);
También es posible usar un proxy SOCKS cuando se conecta a un socket TCP. Primero, usamos la instancia de Proxy para construir un Socket. Luego, pasamos la instancia de destino de SocketAddress a Socket.connect() de la siguiente manera:
Socket proxySocket = nuevo Socket(socksProxy);
InetSocketAddress socketHost = new InetSocketAddress(SOCKET_SERVER_HOST, SOCKET_SERVER_PORT);
proxySocket.conectar(socketHost);
Ejemplo:
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) { } } } } }
Producción:
Conclusión: según el resultado, observamos cómo trabajar con servidores proxy en el núcleo de Java. Primero, observamos el estilo más antiguo y global de conectarse a través de servidores proxy utilizando las propiedades del sistema. Luego, vimos cómo usar la clase Proxy, que proporciona un control detallado cuando se conecta a través de servidores proxy.
Publicación traducida automáticamente
Artículo escrito por sanketnagare y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA