Restlet framework: how to bind to localhost only?

742 Views Asked by At

I need to build a (standalone Java) restlet-based service that only listens on localhost, i.e. no requests from network are allowed.

I was trying to do the obvious:

Server srv = new Server(Protocol.HTTPS, "localhost", httpsPort); 
component.getServers().add(srv);

But the service still listens on 0.0.0.0. :-(

I went into the code and found that HttpsServerHelper ignores the hostname when creating the service:

this.server = HttpsServer.create(new InetSocketAddress(getHelped().getPort()), 0);

Similar code exists in plain HTTP's HttpServerHelper, where it is even more clear.

My question then is this:

How can I configure Restlet component/service to only listen on localhost?

2

There are 2 best solutions below

3
Thierry Templier On BEST ANSWER

I don't know which server you use under the hood within your standalone Restlet application. You should use a server connector other than the default one and I recommend you to use the Jetty one.

To do that, simply put the jar of the extension org.restlet.ext.jetty in your classpath.

In this case, using the following code should correspond to your needs:

component.getServers().add(Protocol.HTTP, "localhost", 8182);

Here is the corresponding trace at application startup:

2015-09-03 09:47:22.180:INFO::jetty-7.1.6.v20100715
2015-09-03 09:47:22.211:INFO::Started SelectChannelConnector@localhost:8182

In addition, here is the link in the Restlet documentation regarding Restlet connectors: http://restlet.com/technical-resources/restlet-framework/guide/2.3/core/base/connectors.

Hope it helps you, Thierry

1
Thierry Boileau On

The easier way to achieve that is to use virtual hosts. Virtual hosts are the first routing barrier when handling a request, especially it helps routing on a domain.

Here is a sample code that illustrates this:

    Component c = new Component();
    c.getServers().add(Protocol.HTTP, 8182);

    VirtualHost host = new VirtualHost();
    host.setHostDomain("localhost");
    c.getHosts().add(host);
    host.attach(new Restlet() {
        @Override
        public void handle(Request request, Response response) {
            response.setEntity("hello, world", MediaType.TEXT_PLAIN);
        }
    });

    c.start();

Usually, applications are attached on the default host of a component. This default host does nothing, except routing requests based on the context path of the attached application:

    c.getDefaultHost().attach("/contextPath1", new Test1Application());
    c.getDefaultHost().attach("/contextPath2", new Test2Application());

When you would like to filter calls based on other data than the request's path, virtual host may be the solution.

Here is a diagram that may help you:

http://restlet.com/technical-resources/restlet-framework/tutorials/2.3#part05