Browse Source

Merge pull request #80 from ntrp/master

fixed flashsocket resource handler from outbound to inbound
master
Nikita Koksharov 12 years ago
parent
commit
544d16b835
  1. 95
      src/main/java/com/corundumstudio/socketio/handler/ResourceHandler.java

95
src/main/java/com/corundumstudio/socketio/handler/ResourceHandler.java

@ -26,8 +26,7 @@ import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.DefaultFileRegion; import io.netty.channel.DefaultFileRegion;
import io.netty.channel.FileRegion; import io.netty.channel.FileRegion;
import io.netty.handler.codec.http.DefaultHttpResponse; import io.netty.handler.codec.http.DefaultHttpResponse;
@ -59,7 +58,7 @@ import java.util.TimeZone;
import javax.activation.MimetypesFileTypeMap; import javax.activation.MimetypesFileTypeMap;
@Sharable @Sharable
public class ResourceHandler extends ChannelOutboundHandlerAdapter {
public class ResourceHandler extends ChannelInboundHandlerAdapter {
public static final String HTTP_DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss zzz"; public static final String HTTP_DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss zzz";
public static final String HTTP_DATE_GMT_TIMEZONE = "GMT"; public static final String HTTP_DATE_GMT_TIMEZONE = "GMT";
@ -74,7 +73,7 @@ public class ResourceHandler extends ChannelOutboundHandlerAdapter {
"/static/flashsocket/WebSocketMainInsecure.swf"); "/static/flashsocket/WebSocketMainInsecure.swf");
} }
private void addResource(String pathPart, String resourcePath) {
public void addResource(String pathPart, String resourcePath) {
URL resource = getClass().getResource(resourcePath); URL resource = getClass().getResource(resourcePath);
// in case of usage exclude-swf-files profile // in case of usage exclude-swf-files profile
if (resource != null) { if (resource != null) {
@ -83,43 +82,47 @@ public class ResourceHandler extends ChannelOutboundHandlerAdapter {
} }
} }
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
if (msg instanceof FullHttpRequest) {
FullHttpRequest req = (FullHttpRequest) msg;
QueryStringDecoder queryDecoder = new QueryStringDecoder(req.getUri());
File resource = resources.get(queryDecoder.path());
if (resource != null) {
HttpResponse res = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.OK);
if (isNotModified(req, resource)) {
sendNotModified(ctx);
req.release();
return;
}
req.release();
RandomAccessFile raf;
try {
raf = new RandomAccessFile(resource, "r");
} catch (FileNotFoundException fnfe) {
sendError(ctx, NOT_FOUND);
return;
}
long fileLength = raf.length();
setContentLength(res, fileLength);
setContentTypeHeader(res, resource);
setDateAndCacheHeaders(res, resource);
writeContent(raf, fileLength, ctx.channel());
return;
}
}
// TODO Auto-generated method stub
super.write(ctx, msg, promise);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof FullHttpRequest) {
FullHttpRequest req = (FullHttpRequest) msg;
QueryStringDecoder queryDecoder = new QueryStringDecoder(req.getUri());
File resource = resources.get(queryDecoder.path());
if (resource != null) {
HttpResponse res = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.OK);
if (isNotModified(req, resource)) {
sendNotModified(ctx);
req.release();
return;
}
RandomAccessFile raf;
try {
raf = new RandomAccessFile(resource, "r");
} catch (FileNotFoundException fnfe) {
sendError(ctx, NOT_FOUND);
return;
}
long fileLength = raf.length();
setContentLength(res, fileLength);
setContentTypeHeader(res, resource);
setDateAndCacheHeaders(res, resource);
// write the response header
ctx.write(res);
// write the content to the channel
ChannelFuture writeFuture = writeContent(raf, fileLength, ctx.channel());
// close the request channel
writeFuture.addListener(ChannelFutureListener.CLOSE);
return;
}
}
super.channelRead(ctx, msg);
}
private boolean isNotModified(HttpRequest request, File file) throws ParseException { private boolean isNotModified(HttpRequest request, File file) throws ParseException {
String ifModifiedSince = request.headers().get(HttpHeaders.Names.IF_MODIFIED_SINCE); String ifModifiedSince = request.headers().get(HttpHeaders.Names.IF_MODIFIED_SINCE);
if (ifModifiedSince != null && !ifModifiedSince.equals("")) { if (ifModifiedSince != null && !ifModifiedSince.equals("")) {
@ -157,7 +160,7 @@ public class ResourceHandler extends ChannelOutboundHandlerAdapter {
HttpHeaders.setHeader(response, HttpHeaders.Names.DATE, dateFormatter.format(time.getTime())); HttpHeaders.setHeader(response, HttpHeaders.Names.DATE, dateFormatter.format(time.getTime()));
} }
private void writeContent(RandomAccessFile raf, long fileLength, Channel ch) throws IOException {
private ChannelFuture writeContent(RandomAccessFile raf, long fileLength, Channel ch) throws IOException {
ChannelFuture writeFuture; ChannelFuture writeFuture;
if (ch.pipeline().get(SslHandler.class) != null) { if (ch.pipeline().get(SslHandler.class) != null) {
// Cannot use zero-copy with HTTPS. // Cannot use zero-copy with HTTPS.
@ -166,15 +169,9 @@ public class ResourceHandler extends ChannelOutboundHandlerAdapter {
// No encryption - use zero-copy. // No encryption - use zero-copy.
final FileRegion region = new DefaultFileRegion(raf.getChannel(), 0, fileLength); final FileRegion region = new DefaultFileRegion(raf.getChannel(), 0, fileLength);
writeFuture = ch.write(region); writeFuture = ch.write(region);
writeFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
region.release();
}
});
} }
writeFuture.addListener(ChannelFutureListener.CLOSE);
return writeFuture;
} }
private void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) { private void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) {

Loading…
Cancel
Save