[#441] Update HTTP examples so that they understand DecoderResult

This commit is contained in:
Trustin Lee 2012-09-28 15:42:38 +09:00
parent 623956b838
commit 045b621b3f
5 changed files with 58 additions and 17 deletions

View File

@ -25,7 +25,6 @@ import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundMessageHandlerAdapter; import io.netty.channel.ChannelInboundMessageHandlerAdapter;
import io.netty.handler.codec.TooLongFrameException;
import io.netty.handler.codec.http.DefaultHttpResponse; import io.netty.handler.codec.http.DefaultHttpResponse;
import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpRequest;
@ -104,6 +103,11 @@ public class HttpStaticFileServerHandler extends ChannelInboundMessageHandlerAda
public void messageReceived( public void messageReceived(
ChannelHandlerContext ctx, HttpRequest request) throws Exception { ChannelHandlerContext ctx, HttpRequest request) throws Exception {
if (!request.getDecoderResult().isSuccess()) {
sendError(ctx, BAD_REQUEST);
return;
}
if (request.getMethod() != GET) { if (request.getMethod() != GET) {
sendError(ctx, METHOD_NOT_ALLOWED); sendError(ctx, METHOD_NOT_ALLOWED);
return; return;
@ -172,13 +176,7 @@ public class HttpStaticFileServerHandler extends ChannelInboundMessageHandlerAda
} }
@Override @Override
public void exceptionCaught( public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (cause instanceof TooLongFrameException) {
sendError(ctx, BAD_REQUEST);
return;
}
cause.printStackTrace(); cause.printStackTrace();
if (ctx.channel().isActive()) { if (ctx.channel().isActive()) {
sendError(ctx, INTERNAL_SERVER_ERROR); sendError(ctx, INTERNAL_SERVER_ERROR);

View File

@ -25,12 +25,14 @@ import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundMessageHandlerAdapter; import io.netty.channel.ChannelInboundMessageHandlerAdapter;
import io.netty.handler.codec.DecoderResult;
import io.netty.handler.codec.http.Cookie; import io.netty.handler.codec.http.Cookie;
import io.netty.handler.codec.http.CookieDecoder; import io.netty.handler.codec.http.CookieDecoder;
import io.netty.handler.codec.http.DefaultHttpResponse; import io.netty.handler.codec.http.DefaultHttpResponse;
import io.netty.handler.codec.http.HttpChunk; import io.netty.handler.codec.http.HttpChunk;
import io.netty.handler.codec.http.HttpChunkTrailer; import io.netty.handler.codec.http.HttpChunkTrailer;
import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.QueryStringDecoder; import io.netty.handler.codec.http.QueryStringDecoder;
@ -66,12 +68,15 @@ public class HttpSnoopServerHandler extends ChannelInboundMessageHandlerAdapter<
buf.append("HOSTNAME: ").append(getHost(request, "unknown")).append("\r\n"); buf.append("HOSTNAME: ").append(getHost(request, "unknown")).append("\r\n");
buf.append("REQUEST_URI: ").append(request.getUri()).append("\r\n\r\n"); buf.append("REQUEST_URI: ").append(request.getUri()).append("\r\n\r\n");
List<Map.Entry<String, String>> headers = request.getHeaders();
if (!headers.isEmpty()) {
for (Map.Entry<String, String> h: request.getHeaders()) { for (Map.Entry<String, String> h: request.getHeaders()) {
String key = h.getKey(); String key = h.getKey();
String value = h.getValue(); String value = h.getValue();
buf.append("HEADER: ").append(key).append(" = ").append(value).append("\r\n"); buf.append("HEADER: ").append(key).append(" = ").append(value).append("\r\n");
} }
buf.append("\r\n"); buf.append("\r\n");
}
QueryStringDecoder queryStringDecoder = new QueryStringDecoder(request.getUri()); QueryStringDecoder queryStringDecoder = new QueryStringDecoder(request.getUri());
Map<String, List<String>> params = queryStringDecoder.getParameters(); Map<String, List<String>> params = queryStringDecoder.getParameters();
@ -95,7 +100,8 @@ public class HttpSnoopServerHandler extends ChannelInboundMessageHandlerAdapter<
buf.append(content.toString(CharsetUtil.UTF_8)); buf.append(content.toString(CharsetUtil.UTF_8));
buf.append("\r\n"); buf.append("\r\n");
} }
writeResponse(ctx); appendDecoderResult(buf, request);
writeResponse(ctx, request);
} }
} else { } else {
HttpChunk chunk = (HttpChunk) msg; HttpChunk chunk = (HttpChunk) msg;
@ -115,20 +121,39 @@ public class HttpSnoopServerHandler extends ChannelInboundMessageHandlerAdapter<
buf.append("\r\n"); buf.append("\r\n");
} }
writeResponse(ctx); appendDecoderResult(buf, chunk);
writeResponse(ctx, chunk);
} else { } else {
buf.append("CHUNK: "); buf.append("CHUNK: ");
buf.append(chunk.getContent().toString(CharsetUtil.UTF_8)).append("\r\n"); buf.append(chunk.getContent().toString(CharsetUtil.UTF_8)).append("\r\n");
appendDecoderResult(buf, chunk);
} }
} }
} }
private void writeResponse(ChannelHandlerContext ctx) { private static void appendDecoderResult(StringBuilder buf, HttpObject o) {
DecoderResult result = o.getDecoderResult();
if (result.isSuccess()) {
return;
}
buf.append(".. WITH A ");
if (result.isPartial()) {
buf.append("PARTIAL ");
}
buf.append("DECODER FAILURE: ");
buf.append(result.cause());
buf.append("\r\n");
}
private void writeResponse(ChannelHandlerContext ctx, HttpObject currentObj) {
// Decide whether to close the connection or not. // Decide whether to close the connection or not.
boolean keepAlive = isKeepAlive(request); boolean keepAlive = isKeepAlive(request);
// Build the response object. // Build the response object.
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK); HttpResponse response = new DefaultHttpResponse(
HTTP_1_1, currentObj.getDecoderResult().isSuccess()? OK : BAD_REQUEST);
response.setContent(Unpooled.copiedBuffer(buf.toString(), CharsetUtil.UTF_8)); response.setContent(Unpooled.copiedBuffer(buf.toString(), CharsetUtil.UTF_8));
response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8"); response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8");

View File

@ -59,6 +59,12 @@ public class AutobahnServerHandler extends ChannelInboundMessageHandlerAdapter<O
} }
private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception { private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception {
// Handle a bad request.
if (!req.getDecoderResult().isSuccess()) {
sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, BAD_REQUEST));
return;
}
// Allow only GET methods. // Allow only GET methods.
if (req.getMethod() != GET) { if (req.getMethod() != GET) {
sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN)); sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN));

View File

@ -61,6 +61,12 @@ public class WebSocketServerHandler extends ChannelInboundMessageHandlerAdapter<
} }
private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception { private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception {
// Handle a bad request.
if (!req.getDecoderResult().isSuccess()) {
sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, BAD_REQUEST));
return;
}
// Allow only GET methods. // Allow only GET methods.
if (req.getMethod() != GET) { if (req.getMethod() != GET) {
sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN)); sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN));

View File

@ -62,6 +62,12 @@ public class WebSocketSslServerHandler extends ChannelInboundMessageHandlerAdapt
} }
private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception { private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception {
// Handle a bad request.
if (!req.getDecoderResult().isSuccess()) {
sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, BAD_REQUEST));
return;
}
// Allow only GET methods. // Allow only GET methods.
if (req.getMethod() != GET) { if (req.getMethod() != GET) {
sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN)); sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN));