I've followed many tutorials and sample sample code but I am yet to see a way to access client's HTTP header, hostname etc like the way we can in Servlet's request object.
How do I go about it?
Let's say I've onOpen defined as-
@OnOpen
public void onOpen(Session session) {
}
In above method, is there a way I can access underlying HTTP connection details using session field? I am okay even if I can get to underlying Servlet (if there is any)
see chapter 4.1.1.5 at Tyrus user guide. It requires some amount of work to get the info from ServerEnpointConfig.Configurator to endpoint instance, but it can be done. (see ModifyRequestResponseHeadersTest.java)
Based on link1
and link2
I finally figured out that we can get the client IP with the following two classes, actually you can do more with the exposed httpservletRequest...
ServletAwareConfigurator .java
package examples;
import java.lang.reflect.Field;
import javax.servlet.http.HttpServletRequest;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
import javax.websocket.server.ServerEndpointConfig.Configurator;
public class ServletAwareConfigurator extends ServerEndpointConfig.Configurator {
@Override
public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) {
HttpServletRequest httpservletRequest = getField(request, HttpServletRequest.class);
String sClientIP = httpservletRequest.getRemoteAddr();
config.getUserProperties().put("clientip", sClientIP);
// ...
}
//hacking reflector to expose fields...
private static < I, F > F getField(I instance, Class < F > fieldType) {
try {
for (Class < ? > type = instance.getClass(); type != Object.class; type = type.getSuperclass()) {
for (Field field: type.getDeclaredFields()) {
if (fieldType.isAssignableFrom(field.getType())) {
field.setAccessible(true);
return (F) field.get(instance);
}
}
}
} catch (Exception e) {
// Handle?
}
return null;
}
}
GetHttpSessionSocket.java
package examples;
import java.io.IOException;
import javax.servlet.http.HttpSession;
import javax.websocket.EndpointConfig;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint(value = "/example",
configurator = ServletAwareConfigurator.class)
public class GetHttpSessionSocket {
private Session wsSession;
private String sClientIP;
@OnOpen
public void open(Session session, EndpointConfig config) {
this.wsSession = session;
this.sClientIP = (String) config.getUserProperties()
.get("clientip");
}
@OnMessage
public void echo(String msg) throws IOException {
wsSession.getBasicRemote().sendText(msg);
}
}