From ce819ee758283c0c541a57072115e1e6385214e5 Mon Sep 17 00:00:00 2001 From: Nikita Date: Wed, 9 May 2012 18:14:03 +0400 Subject: [PATCH] Authorize refactoring --- .../socketio/AuthorizeHandler.java | 50 ++++++++++++++++--- .../transport/WebSocketTransport.java | 1 - .../socketio/transport/XHRPollingClient.java | 6 +-- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/corundumstudio/socketio/AuthorizeHandler.java b/src/main/java/com/corundumstudio/socketio/AuthorizeHandler.java index bbf6aef..9a9ea02 100644 --- a/src/main/java/com/corundumstudio/socketio/AuthorizeHandler.java +++ b/src/main/java/com/corundumstudio/socketio/AuthorizeHandler.java @@ -15,6 +15,10 @@ */ package com.corundumstudio.socketio; +import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.CONNECTION; +import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE; +import static org.jboss.netty.handler.codec.http.HttpHeaders.Values.KEEP_ALIVE; + import java.io.IOException; import java.util.Collections; import java.util.Iterator; @@ -26,13 +30,20 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import org.codehaus.jackson.map.ObjectMapper; +import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelUpstreamHandler; +import org.jboss.netty.handler.codec.http.DefaultHttpResponse; +import org.jboss.netty.handler.codec.http.HttpHeaders; import org.jboss.netty.handler.codec.http.HttpMethod; import org.jboss.netty.handler.codec.http.HttpRequest; +import org.jboss.netty.handler.codec.http.HttpResponse; +import org.jboss.netty.handler.codec.http.HttpResponseStatus; +import org.jboss.netty.handler.codec.http.HttpVersion; import org.jboss.netty.handler.codec.http.QueryStringDecoder; +import org.jboss.netty.util.CharsetUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -83,12 +94,11 @@ public class AuthorizeHandler extends SimpleChannelUpstreamHandler implements Di ctx.sendUpstream(e); } - private void authorize(Channel channel, HttpRequest msg, Map> params) + private void authorize(Channel channel, HttpRequest req, Map> params) throws IOException { removeStaleAuthorizedIds(); // TODO use common client final UUID sessionId = UUID.randomUUID(); - XHRPollingClient client = new XHRPollingClient(encoder, this, null); authorizedSessionIds.put(sessionId, System.currentTimeMillis()); String transports = "xhr-polling,websocket"; @@ -98,19 +108,43 @@ public class AuthorizeHandler extends SimpleChannelUpstreamHandler implements Di heartbeatTimeoutVal = ""; } - String hs = sessionId + ":" + heartbeatTimeoutVal + ":" + configuration.getCloseTimeout() + ":" + transports; + boolean jsonp = false; + String msg = sessionId + ":" + heartbeatTimeoutVal + ":" + configuration.getCloseTimeout() + ":" + transports; List jsonpParam = params.get("jsonp"); if (jsonpParam != null) { - String jsonpResponse = "io.j[" + jsonpParam.get(0) + "](" + objectMapper.writeValueAsString(hs) + ");"; - client.sendJsonp(jsonpResponse); - } else { - client.sendUnencoded(hs); + jsonp = true; + msg = "io.j[" + jsonpParam.get(0) + "](" + objectMapper.writeValueAsString(msg) + ");"; } - client.doReconnect(channel, msg); + + sendResponse(req, channel, sessionId, msg, jsonp); log.debug("New sessionId: {} authorized", sessionId); } + private void addHeaders(HttpResponse res, String origin, boolean jsonp) { + res.addHeader(CONTENT_TYPE, "text/plain; charset=UTF-8"); + res.addHeader(CONNECTION, KEEP_ALIVE); + if (origin != null) { + res.addHeader("Access-Control-Allow-Origin", origin); + res.addHeader("Access-Control-Allow-Credentials", "true"); + } + if (jsonp) { + res.addHeader(CONTENT_TYPE, "application/javascript"); + } + } + + private void sendResponse(HttpRequest req, Channel channel, UUID sessionId, String message, boolean jsonp) { + HttpResponse res = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); + String origin = req.getHeader(HttpHeaders.Names.ORIGIN); + addHeaders(res, origin, jsonp); + + res.setContent(ChannelBuffers.copiedBuffer(message, CharsetUtil.UTF_8)); + HttpHeaders.setContentLength(res, res.getContent().readableBytes()); + + log.trace("Out message: {} sessionId: {}", new Object[] {message, sessionId}); + channel.write(res); + } + public boolean isSessionAuthorized(UUID sessionId) { return connectedSessionIds.contains(sessionId) || authorizedSessionIds.containsKey(sessionId); diff --git a/src/main/java/com/corundumstudio/socketio/transport/WebSocketTransport.java b/src/main/java/com/corundumstudio/socketio/transport/WebSocketTransport.java index 37b5cae..d7ec1ae 100644 --- a/src/main/java/com/corundumstudio/socketio/transport/WebSocketTransport.java +++ b/src/main/java/com/corundumstudio/socketio/transport/WebSocketTransport.java @@ -15,7 +15,6 @@ */ package com.corundumstudio.socketio.transport; -import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.CONNECTION; import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.SEC_WEBSOCKET_KEY; import static org.jboss.netty.handler.codec.http.HttpHeaders.Values.WEBSOCKET; diff --git a/src/main/java/com/corundumstudio/socketio/transport/XHRPollingClient.java b/src/main/java/com/corundumstudio/socketio/transport/XHRPollingClient.java index 03609df..7e6b5be 100644 --- a/src/main/java/com/corundumstudio/socketio/transport/XHRPollingClient.java +++ b/src/main/java/com/corundumstudio/socketio/transport/XHRPollingClient.java @@ -55,7 +55,6 @@ public class XHRPollingClient implements SocketIOClient { private final UUID sessionId; private String origin; - private boolean isKeepAlive; private boolean connected; private Channel channel; @@ -73,7 +72,6 @@ public class XHRPollingClient implements SocketIOClient { } public void doReconnect(Channel channel, HttpRequest req) { - this.isKeepAlive = HttpHeaders.isKeepAlive(req); this.origin = req.getHeader(HttpHeaders.Names.ORIGIN); this.channel = channel; this.connected = true; @@ -103,9 +101,7 @@ public class XHRPollingClient implements SocketIOClient { if (channel.isConnected()) { log.trace("Out message: {} sessionId: {}", new Object[] {message, sessionId}); ChannelFuture f = channel.write(res); - if (!isKeepAlive) { - f.addListener(ChannelFutureListener.CLOSE); - } + f.addListener(ChannelFutureListener.CLOSE); return f; } return NullChannelFuture.INSTANCE;