Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

apache tomcat 8 websocket origin and client address

H.e.l.l.o community, i hope someone can help me ... i am using apache tomcat 8.0.0-RC5 and JSR-356 web socket API ... I have 2 questions:

1) Is it possible to get the client ip on @OnOpen method ??

2) Is it possible to get the origin of the connection ???

I followed the websocket example which comes with the distribution of tomcat and i was not able to find the answers .... My java class is basically as follow

@ServerEndpoint(value = "/data.socket")
public class MyWebSocket {
    @OnOpen
    public void onOpen(Session session) {
        // Here is where i need the origin and remote client address
    }

    @OnClose
    public void onClose() {
        // disconnection handling
    }

    @OnMessage
    public void onMessage(String message) {
        // message handling
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        // Error handling
    }
}
like image 735
user2926082 Avatar asked Mar 21 '26 10:03

user2926082


1 Answers

I know this question is old, but just in case someone else finds it in a web search:

Yes there is an easy workaround. A Servlet can receive and forward a WebSocket upgrade request. The trick is to get the client IP address and expose it as a parameter.

Here's your servlet code:

@WebServlet("/myExternalEntryPoint")
public class WebSocketServlet extends HttpServlet {
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        var dispatcher = getServletContext().getRequestDispatcher("/myInternalEntryPoint");
        var requestWrapper = new MyRequestWrapper(request);
        dispatcher.forward(requestWrapper, response);
    }
}

And here's MyRequestWrapper:

class MyRequestWrapper extends HttpServletRequestWrapper {
    public RequestWrapper(HttpServletRequest request) {
        super(request);
    }

    public Map<String, String[]> getParameterMap() {
        return Collections.singletonMap("remoteAddr", new String[] {getRequest().getRemoteAddr()});
    }
}

Now in your WebSocket implementation, you'll be able to get remoteAddr via javax.websocket.Session.getRequestParameterMap().

Naturally, if your original request has parameters that you care about, you'll need to create a map that includes those as well. Also I recommend you append a separate, secret parameter and check for it in your WebSocket code to prevent anyone from hitting the internal entry point directly.

I figured out this was possible because of this thoughtful comment in the Tomcat source code (WsFilter.java):

// No endpoint registered for the requested path. Let the
// application handle it (it might redirect or forward for example)
like image 174
Ian Lovejoy Avatar answered Mar 23 '26 22:03

Ian Lovejoy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!