Grizzly + Jersey Listens ONLY on Localhost

I am using Jersey with the built-in version of Grizzly and I would like to snap / listen on localhost ONLY. I create a ThreadSelector using a GrizzlyWebContainerFactory with a create call:

threadSelector = GrizzlyWebContainerFactory.create("http://127.0.0.1:8080/", initParams); 

This works, but I can still get to the server from an external machine. How can I make it bind / listen on the local host ONLY?

This is for configuration materials, so I don’t want anything from the window to be available for connecting to this server.

+6
source share
2 answers

I was able to do this using the localhost in Jersey 2.3.1 with the built-in version of Grizzly:

 import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; // ... GrizzlyHttpServerFactory.createHttpServer( URI.create("http://localhost:9580/my-app/") ); 

Test results in:

 > curl -I http://myhost.com:9580/my-app curl: (7) couldn't connect to host 

While starting a Grizzly server with a URI of "http://0.0.0.0:9580/my-app/" or "http://myhost.com:9580/my-app/" , I can hit it with

 > curl -I http://myhost.com:9580/my-app HTTP/1.1 200 Not Found ... 

Here's a table where hosts work with URLs when using GrizzlyHttpServerFactory . As far as I know, there are no surprises:

 # For http://0.0.0.0:9575/my-app | Works? curl -I http://0.0.0.0:9575/my-app | Yes curl -I http://127.0.0.1:9575/my-app | Yes curl -I http://localhost:9575/my-app | Yes curl -I http://myhost.com:9575/my-app | Yes | # For http://127.0.0.1:9575/my-app | # For http://localhost:9575/my-app | curl -I http://0.0.0.0:9575/my-app | Yes curl -I http://127.0.0.1:9575/my-app | Yes curl -I http://localhost:9575/my-app | Yes curl -I http://myhost.com:9575/my-app | No | # For http://myhost.com:9585/my-app | curl -I http://0.0.0.0:9585/my-app | No curl -I http://127.0.0.1:9585/my-app | No curl -I http://localhost:9575/my-app | No curl -I http://myhost.com:9585/my-app | Yes 
+11
source

You can easily extend the GrizzlyWebContainerFactory to support this requirement (since the class is final, I created a standalone utility that allows you to bind a listening socket to localhost). You can use this utility as:

 SelectorThread threadSelector = GrizzlyWebContainerFactoryUtil.create("http://127.0.0.1:8080/", initParams, true); 

Setting the last parameter to true causes it to bind to localhost. The only code I added to support this requirement is:

 selectorThread.setAddress(InetAddress.getByName("localhost")); 

The entire utility class is shown below:

 import com.sun.grizzly.http.SelectorThread; import com.sun.grizzly.http.servlet.ServletAdapter; import com.sun.grizzly.standalone.StaticStreamAlgorithm; import com.sun.grizzly.tcp.Adapter; import com.sun.grizzly.tcp.http11.GrizzlyAdapter; import com.sun.jersey.api.container.ContainerException; import com.sun.jersey.api.core.ClasspathResourceConfig; import com.sun.jersey.spi.container.servlet.ServletContainer; import javax.servlet.Servlet; import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.net.URI; import java.util.Map; public class GrizzlyWebContainerFactoryUtil { public static SelectorThread create(String u, Map<String, String> initParams, boolean localHostOnly) throws IOException, IllegalArgumentException { if (u == null) throw new IllegalArgumentException("The URI must not be null"); return create(URI.create(u), initParams, localHostOnly); } public static SelectorThread create(URI u, Map<String, String> initParams, boolean localHostOnly) throws IOException { return create(u, ServletContainer.class, initParams, localHostOnly); } public static SelectorThread create(URI u, Class<? extends Servlet> c, Map<String, String> initParams, boolean localHostOnly) throws IOException { if (u == null) throw new IllegalArgumentException("The URI must not be null"); ServletAdapter adapter = new ServletAdapter(); if (initParams == null) { adapter.addInitParameter(ClasspathResourceConfig.PROPERTY_CLASSPATH, System.getProperty("java.class.path").replace(File.pathSeparatorChar, ';')); } else { for (Map.Entry<String, String> e : initParams.entrySet()) { adapter.addInitParameter(e.getKey(), e.getValue()); } } adapter.setServletInstance(getInstance(c)); String path = u.getPath(); if (path == null) throw new IllegalArgumentException("The URI path, of the URI " + u + ", must be non-null"); else if (path.length() == 0) throw new IllegalArgumentException("The URI path, of the URI " + u + ", must be present"); else if (path.charAt(0) != '/') throw new IllegalArgumentException("The URI path, of the URI " + u + ". must start with a '/'"); if (path.length() > 1) { if (path.endsWith("/")) path = path.substring(0, path.length() - 1); adapter.setContextPath(path); } return create(u, adapter, localHostOnly); } private static Servlet getInstance(Class<? extends Servlet> c) { try { return c.newInstance(); } catch (Exception e) { throw new ContainerException(e); } } public static SelectorThread create(URI u, Adapter adapter, boolean localHostOnly) throws IOException, IllegalArgumentException { if (u == null) throw new IllegalArgumentException("The URI must not be null"); // TODO support https final String scheme = u.getScheme(); if (!scheme.equalsIgnoreCase("http")) throw new IllegalArgumentException("The URI scheme, of the URI " + u + ", must be equal (ignoring case) to 'http'"); if (adapter instanceof GrizzlyAdapter) { GrizzlyAdapter ga = (GrizzlyAdapter) adapter; ga.setResourcesContextPath(u.getRawPath()); } final SelectorThread selectorThread = new SelectorThread(); selectorThread.setAlgorithmClassName(StaticStreamAlgorithm.class.getName()); final int port = (u.getPort() == -1) ? 80 : u.getPort(); selectorThread.setPort(port); if (localHostOnly) { selectorThread.setAddress(InetAddress.getByName("localhost")); } selectorThread.setAdapter(adapter); try { selectorThread.listen(); } catch (InstantiationException e) { IOException _e = new IOException(); _e.initCause(e); throw _e; } return selectorThread; } } 
-2
source

Source: https://habr.com/ru/post/888468/


All Articles