}
@Override
public Action inspect(final AtmosphereResource r) {
final AtmosphereRequest request = r.getRequest();
r.addEventListener(new AtmosphereResourceEventListenerAdapter() {
/**
* {@inheritDoc}
*/
@Override
public void onSuspend(AtmosphereResourceEvent event) {
AsyncIOWriter writer = event.getResource().getResponse().getAsyncIOWriter();
if (writer == null) {
writer = new AtmosphereInterceptorWriter();
r.getResponse().asyncIOWriter(writer);
}
if (AtmosphereInterceptorWriter.class.isAssignableFrom(writer.getClass())) {
AtmosphereInterceptorWriter.class.cast(writer).interceptor(interceptor);
}
}
});
boolean ok = false;
if (request.getHeader("SwaggerSocket") != null) {
ok = true;
}
if (ok && request.getAttribute(SWAGGER_SOCKET_DISPATCHED) == null) {
AtmosphereResponse response = r.getResponse();
response.setContentType("application/json");
logger.debug("Method {} Transport {}", request.getMethod(), r.transport());
// Suspend to keep the connection OPEN.
if (request.getMethod() == "GET" && r.transport().equals(AtmosphereResource.TRANSPORT.LONG_POLLING)) {
r.resumeOnBroadcast(true).suspend();
BlockingQueue<AtmosphereResource> queue = (BlockingQueue<AtmosphereResource>)
getContextValue(request, SUSPENDED_RESPONSE);
if (queue == null) {
queue = new LinkedBlockingQueue<AtmosphereResource>();
request.getSession().setAttribute(SUSPENDED_RESPONSE, queue);
}
queue.offer(r);
String identity = (String) getContextValue(request, IDENTITY);
schedule(r, identity);
return Action.SUSPEND;
}
AtmosphereFramework framework = r.getAtmosphereConfig().framework();
StringBuilder d = new StringBuilder();
try {
InputStreamReader isr = new InputStreamReader(request.getInputStream());
BufferedReader bufReader = new BufferedReader(isr);
char[] charBuffer = new char[8192];
for (int readCount = bufReader.read(charBuffer); readCount > -1; readCount = bufReader.read(charBuffer)) {
d.append(charBuffer, 0, readCount);
}
String data = d.toString();
if (data.length() == 0) {
return Action.CANCELLED;
}
String message = data.substring(0, 20).replaceAll(" ", "");
logger.debug(data);
if (message.startsWith("{\"handshake\"")) {
// This will fail if the message is not well formed.
HandshakeMessage handshakeMessage = mapper.readValue(data, HandshakeMessage.class);
// If we missed the CloseReason for whatever reason (IE is a good candidate), make sure we swap the previous session anyway.
String identity = (String) getContextValue(request, IDENTITY);
if (identity == null) {
identity = UUID.randomUUID().toString();
} else {
logger.debug("Client disconnected {}, cleaning session {}", identity);
try {
Enumeration<String> e = request.getSession().getAttributeNames();
while (e.hasMoreElements()) {
request.getSession().removeAttribute(e.nextElement());
}
} catch (Exception ex) {
logger.warn("", ex);
}
}
addContextValue(request, IDENTITY, identity);
StatusMessage statusMessage = new StatusMessage.Builder().status(new StatusMessage.Status(200, "OK"))
.identity(identity).build();
response.setContentType("application/json");
response.getOutputStream().write(mapper.writeValueAsBytes(statusMessage));
if (r.transport() == AtmosphereResource.TRANSPORT.WEBSOCKET) {
schedule(r, identity);
}
if (!delegateHandshake) {
return Action.CANCELLED;
}
} else if (message.startsWith("{\"close\"")) {
CloseMessage c = mapper.readValue(data, CloseMessage.class);
logger.debug("Client disconnected {} with reason {}", c.getClose().getIdentity(), c.getClose().getReason());
try {
request.getSession().invalidate();
} catch (Exception ex) {
logger.warn("", ex);
}
return Action.CANCELLED;
} else {
Message swaggerSocketMessage = mapper.readValue(data, Message.class);
swaggerSocketMessage.transactionID(UUID.randomUUID().toString());
String identity = (String) getContextValue(request, IDENTITY);
if (!swaggerSocketMessage.getIdentity().equals(identity)) {
StatusMessage statusMessage = new StatusMessage.Builder().status(new StatusMessage.Status(503, "Not Allowed"))
.identity(swaggerSocketMessage.getIdentity()).build();
response.getOutputStream().write(mapper.writeValueAsBytes(statusMessage));
return Action.CANCELLED;
}
transactionIdentity.set(swaggerSocketMessage.transactionID());
List<Request> requests = swaggerSocketMessage.getRequests();
addContextValue(request, swaggerSocketMessage.transactionID() + RESPONSE_COUNTER, new AtomicInteger(requests.size()));
AtmosphereRequest ar;
for (Request req : requests) {
ar = toAtmosphereRequest(request, req);
try {
ar.setAttribute(SWAGGER_SOCKET_DISPATCHED, "true");
// This is a new request, we must clean the Websocket AtmosphereResource.
request.removeAttribute(INJECTED_ATMOSPHERE_RESOURCE);
response.request(ar);
attachWriter(r);
ssRequest.set(req);
request.setAttribute("swaggerSocketRequest", req);
Action action = framework.doCometSupport(ar, response);
if (action.type() == Action.TYPE.SUSPEND) {
ar.destroyable(false);
response.destroyable(false);
}
} catch (ServletException e) {
logger.warn("", e);
return Action.CANCELLED;