Browse Source

Throw error if transport not supported. #343

master
Nikita 9 years ago
parent
commit
9cc8c06d1a
  1. 14
      src/main/java/com/corundumstudio/socketio/handler/AuthorizeHandler.java
  2. 41
      src/main/java/com/corundumstudio/socketio/handler/EncoderHandler.java
  3. 18
      src/main/java/com/corundumstudio/socketio/messages/HttpErrorMessage.java
  4. 4
      src/main/java/com/corundumstudio/socketio/protocol/PacketEncoder.java

14
src/main/java/com/corundumstudio/socketio/handler/AuthorizeHandler.java

@ -35,6 +35,7 @@ import com.corundumstudio.socketio.HandshakeData;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.Transport;
import com.corundumstudio.socketio.ack.AckManager;
import com.corundumstudio.socketio.messages.HttpErrorMessage;
import com.corundumstudio.socketio.namespace.Namespace;
import com.corundumstudio.socketio.namespace.NamespacesHub;
import com.corundumstudio.socketio.protocol.AuthPacket;
@ -164,7 +165,7 @@ public class AuthorizeHandler extends ChannelInboundHandlerAdapter implements Di
List<String> transportValue = params.get("transport");
if (transportValue == null) {
log.warn("Got no transports for request {}", req.uri());
log.error("Got no transports for request {}", req.uri());
HttpResponse res = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.UNAUTHORIZED);
channel.writeAndFlush(res).addListener(ChannelFutureListener.CLOSE);
@ -172,11 +173,20 @@ public class AuthorizeHandler extends ChannelInboundHandlerAdapter implements Di
}
Transport transport = Transport.byName(transportValue.get(0));
if (!configuration.getTransports().contains(transport)) {
Map<String, Object> errorData = new HashMap<String, Object>();
errorData.put("code", 0);
errorData.put("message", "Transport unknown");
channel.attr(EncoderHandler.ORIGIN).set(origin);
channel.writeAndFlush(new HttpErrorMessage(errorData));
return false;
}
ClientHead client = new ClientHead(sessionId, ackManager, disconnectable, storeFactory, data, clientsBox, transport, disconnectScheduler, configuration);
channel.attr(ClientHead.CLIENT).set(client);
clientsBox.addClient(client);
String[] transports = {};
if (configuration.getTransports().contains(Transport.WEBSOCKET)) {
transports = new String[] {"websocket"};

41
src/main/java/com/corundumstudio/socketio/handler/EncoderHandler.java

@ -29,6 +29,7 @@ import org.slf4j.LoggerFactory;
import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.Transport;
import com.corundumstudio.socketio.messages.HttpErrorMessage;
import com.corundumstudio.socketio.messages.HttpMessage;
import com.corundumstudio.socketio.messages.OutPacketMessage;
import com.corundumstudio.socketio.messages.XHROptionsMessage;
@ -37,6 +38,7 @@ import com.corundumstudio.socketio.protocol.Packet;
import com.corundumstudio.socketio.protocol.PacketEncoder;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufOutputStream;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
@ -113,7 +115,8 @@ public class EncoderHandler extends ChannelOutboundHandlerAdapter {
.add(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE)
.add(HttpHeaderNames.ACCESS_CONTROL_ALLOW_HEADERS, HttpHeaderNames.CONTENT_TYPE);
addOriginHeaders(ctx.channel(), res);
String origin = ctx.channel().attr(ORIGIN).get();
addOriginHeaders(origin, res);
ByteBuf out = encoder.allocateBuffer(ctx.alloc());
sendMessage(msg, ctx.channel(), out, res, promise);
@ -122,17 +125,20 @@ public class EncoderHandler extends ChannelOutboundHandlerAdapter {
private void write(XHRPostMessage msg, ChannelHandlerContext ctx, ChannelPromise promise) {
ByteBuf out = encoder.allocateBuffer(ctx.alloc());
out.writeBytes(OK);
sendMessage(msg, ctx.channel(), out, "text/html", promise);
sendMessage(msg, ctx.channel(), out, "text/html", promise, HttpResponseStatus.OK);
}
private void sendMessage(HttpMessage msg, Channel channel, ByteBuf out, String type, ChannelPromise promise) {
HttpResponse res = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.OK);
private void sendMessage(HttpMessage msg, Channel channel, ByteBuf out, String type, ChannelPromise promise, HttpResponseStatus status) {
HttpResponse res = new DefaultHttpResponse(HTTP_1_1, status);
res.headers().add(HttpHeaderNames.CONTENT_TYPE, type)
.add(HttpHeaderNames.SET_COOKIE, "io=" + msg.getSessionId())
.add(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
if (msg.getSessionId() != null) {
res.headers().add(HttpHeaderNames.SET_COOKIE, "io=" + msg.getSessionId());
}
addOriginHeaders(channel, res);
String origin = channel.attr(ORIGIN).get();
addOriginHeaders(origin, res);
HttpUtil.setContentLength(res, out.readableBytes());
@ -150,7 +156,11 @@ public class EncoderHandler extends ChannelOutboundHandlerAdapter {
channel.write(res);
if (log.isTraceEnabled()) {
log.trace("Out message: {} - sessionId: {}", out.toString(CharsetUtil.UTF_8), msg.getSessionId());
if (msg.getSessionId() != null) {
log.trace("Out message: {} - sessionId: {}", out.toString(CharsetUtil.UTF_8), msg.getSessionId());
} else {
log.trace("Out message: {}", out.toString(CharsetUtil.UTF_8));
}
}
if (out.isReadable()) {
@ -161,8 +171,16 @@ public class EncoderHandler extends ChannelOutboundHandlerAdapter {
channel.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT, promise).addListener(ChannelFutureListener.CLOSE);
}
private void sendError(HttpErrorMessage errorMsg, ChannelHandlerContext ctx, ChannelPromise promise) throws IOException {
final ByteBuf encBuf = encoder.allocateBuffer(ctx.alloc());
ByteBufOutputStream out = new ByteBufOutputStream(encBuf);
encoder.getJsonSupport().writeValue(out, errorMsg.getData());
sendMessage(errorMsg, ctx.channel(), encBuf, "application/json", promise, HttpResponseStatus.BAD_REQUEST);
}
private void addOriginHeaders(Channel channel, HttpResponse res) {
private void addOriginHeaders(String origin, HttpResponse res) {
if (version != null) {
res.headers().add(HttpHeaderNames.SERVER, version);
}
@ -171,7 +189,6 @@ public class EncoderHandler extends ChannelOutboundHandlerAdapter {
res.headers().add(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, configuration.getOrigin());
res.headers().add(HttpHeaderNames.ACCESS_CONTROL_ALLOW_CREDENTIALS, Boolean.TRUE);
} else {
String origin = channel.attr(ORIGIN).get();
if (origin != null) {
res.headers().add(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, origin);
res.headers().add(HttpHeaderNames.ACCESS_CONTROL_ALLOW_CREDENTIALS, Boolean.TRUE);
@ -200,6 +217,8 @@ public class EncoderHandler extends ChannelOutboundHandlerAdapter {
write((XHROptionsMessage) msg, ctx, promise);
} else if (msg instanceof XHRPostMessage) {
write((XHRPostMessage) msg, ctx, promise);
} else if (msg instanceof HttpErrorMessage) {
sendError((HttpErrorMessage) msg, ctx, promise);
}
}
@ -263,10 +282,10 @@ public class EncoderHandler extends ChannelOutboundHandlerAdapter {
if (jsonpIndex == null) {
type = "text/plain";
}
sendMessage(msg, channel, out, type, promise);
sendMessage(msg, channel, out, type, promise, HttpResponseStatus.OK);
} else {
encoder.encodePackets(queue, out, ctx.alloc(), 50);
sendMessage(msg, channel, out, "application/octet-stream", promise);
sendMessage(msg, channel, out, "application/octet-stream", promise, HttpResponseStatus.OK);
}
}

18
src/main/java/com/corundumstudio/socketio/messages/HttpErrorMessage.java

@ -0,0 +1,18 @@
package com.corundumstudio.socketio.messages;
import java.util.Map;
public class HttpErrorMessage extends HttpMessage {
private final Map<String, Object> data;
public HttpErrorMessage(Map<String, Object> data) {
super(null, null);
this.data = data;
}
public Map<String, Object> getData() {
return data;
}
}

4
src/main/java/com/corundumstudio/socketio/protocol/PacketEncoder.java

@ -46,6 +46,10 @@ public class PacketEncoder {
this.configuration = configuration;
}
public JsonSupport getJsonSupport() {
return jsonSupport;
}
public ByteBuf allocateBuffer(ByteBufAllocator allocator) {
if (configuration.isPreferDirectBuffer()) {
return allocator.ioBuffer();

Loading…
Cancel
Save