@Override public void sendError(ChannelHandlerContext ctx, HttpResponseStatus status, FullHttpRequest e) { // For websocket, we can't send an error logger.trace("Error {} for {}", status, e); if (websocketChannels.contains(ctx.channel())) { logger.debug("Error {} for {}", status, e); ctx.channel().close().addListener(ChannelFutureListener.CLOSE); } else if (e != null) { if (HttpHeaders.getHeader(e, STATIC_MAPPING, "false").equalsIgnoreCase("false")) { super.sendError(ctx, status, e); } } else { super.sendError(ctx, status, e); } }
/** * When file timestamp is the same as what the browser is sending up, send a "304 Not Modified" * * @param ctx * Context */ private static void sendNotModified(ChannelHandlerContext ctx) { FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, NOT_MODIFIED); setDateHeader(response); // Close the connection as soon as the error message is sent. ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); }
@Override public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception { if (!request.decoderResult().isSuccess()) { sendError(ctx, BAD_REQUEST, request); return; sendError(ctx, METHOD_NOT_ALLOWED, request); return; boolean found = true; for (String p : paths) { String path = p + sanitizeUri(request.getUri()); break; } catch (FileNotFoundException ignore) { sendError(ctx, NOT_FOUND, request); return; sendError(ctx, NOT_FOUND, request); return; long fileLastModifiedSeconds = file.lastModified() / 1000; if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) { sendNotModified(ctx); return; contentType(request, response, file); setDateAndCacheHeaders(response, file);
@Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { super.channelInactive(ctx); Object o = ctx.attr(ATTACHMENT).get(); if (o == null) return; if (WebSocket.class.isAssignableFrom(o.getClass())) { NettyWebSocket webSocket = NettyWebSocket.class.cast(o); logger.trace("Closing {}", webSocket.uuid()); try { if (webSocket.closeFuture() != null) { webSocket.closeFuture().cancel(true); } webSocketProcessor.close(webSocket, 1005); } catch (Exception ex) { logger.error("{}", webSocket, ex); } } else if (State.class.isAssignableFrom(o.getClass())) { logger.trace("State {}", o); State s = State.class.cast(o); if (s.action.type() == Action.TYPE.SUSPEND) { asynchronousProcessor.endRequest(s.resource(), true); } } else { logger.warn("Invalid state {} and Channel {}", o, ctx.channel()); } }
@Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable e){ if (config.ioExceptionHandler().of(ctx, e)) { try { if (e instanceof IOException) { logger.trace("Connection closed Exception", e); } else if (e.getCause() != null && (e.getCause().getClass().equals(ClosedChannelException.class) || e.getCause().getClass().equals(IOException.class))) { logger.trace("Unexpected I/O Exception", e.getCause()); } else if (e.getCause() != null && e.getCause().getClass().equals(TooLongFrameException.class)) { logger.error("TooLongFrameException. The request will be closed, make sure you increase the Config.maxChunkContentLength() to a higher value.", e.getCause()); super.exceptionCaught(ctx, e); } else { logger.error("Unexpected and unhandled I/O Exception", e); super.exceptionCaught(ctx, e); } } finally { try { ctx.channel().close(); } catch (Exception ex) { logger.trace("", ex); } } } }
try { hrequest.headers().add(STATIC_MAPPING, "true"); super.channelRead0(ctx, (FullHttpRequest) messageEvent);
@Override public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception { if (!request.decoderResult().isSuccess()) { sendError(ctx, BAD_REQUEST, request); return; sendError(ctx, METHOD_NOT_ALLOWED, request); return; boolean found = true; for (String p : paths) { String path = p + sanitizeUri(request.getUri()); break; } catch (FileNotFoundException ignore) { sendError(ctx, NOT_FOUND, request); return; sendError(ctx, NOT_FOUND, request); return; long fileLastModifiedSeconds = file.lastModified() / 1000; if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) { sendNotModified(ctx); return; contentType(request, response, file); setDateAndCacheHeaders(response, file);
@Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { super.channelInactive(ctx); Object o = ctx.attr(ATTACHMENT).get(); if (o == null) return; if (WebSocket.class.isAssignableFrom(o.getClass())) { NettyWebSocket webSocket = NettyWebSocket.class.cast(o); logger.trace("Closing {}", webSocket.uuid()); try { if (webSocket.closeFuture() != null) { webSocket.closeFuture().cancel(true); } webSocketProcessor.close(webSocket, 1005); } catch (Exception ex) { logger.error("{}", webSocket, ex); } } else if (State.class.isAssignableFrom(o.getClass())) { logger.trace("State {}", o); State s = State.class.cast(o); if (s.action.type() == Action.TYPE.SUSPEND) { asynchronousProcessor.endRequest(s.resource(), true); } } else { logger.warn("Invalid state {} and Channel {}", o, ctx.channel()); } }
@Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable e){ if (config.ioExceptionHandler().of(ctx, e)) { try { if (e instanceof IOException) { logger.trace("Connection closed Exception", e); } else if (e.getCause() != null && (e.getCause().getClass().equals(ClosedChannelException.class) || e.getCause().getClass().equals(IOException.class))) { logger.trace("Unexpected I/O Exception", e.getCause()); } else if (e.getCause() != null && e.getCause().getClass().equals(TooLongFrameException.class)) { logger.error("TooLongFrameException. The request will be closed, make sure you increase the Config.maxChunkContentLength() to a higher value.", e.getCause()); super.exceptionCaught(ctx, e); } else { logger.error("Unexpected and unhandled I/O Exception", e); super.exceptionCaught(ctx, e); } } finally { try { ctx.channel().close(); } catch (Exception ex) { logger.trace("", ex); } } } }
try { hrequest.headers().add(STATIC_MAPPING, "true"); super.channelRead0(ctx, (FullHttpRequest) messageEvent);
@Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable t) { Channel ch = ctx.channel(); // Prevent recursion when the client close the connection during a write operation. In that // scenario the sendError will be invoked, but will fail since the channel has already been closed // For an unknown reason, if (ch.attr(ATTACHMENT) != null && Error.class.isAssignableFrom(ch.attr(ATTACHMENT).get().getClass())) { return; } Throwable cause = t.getCause(); if (cause instanceof TooLongFrameException) { sendError(ctx, BAD_REQUEST, null); return; } ch.attr(ATTACHMENT).set(new Error()); if (ch.isOpen()) { sendError(ctx, INTERNAL_SERVER_ERROR, null); } if (ctx.channel().isActive()) { sendError(ctx, INTERNAL_SERVER_ERROR, null); } }
/** * When file timestamp is the same as what the browser is sending up, send a "304 Not Modified" * * @param ctx * Context */ private static void sendNotModified(ChannelHandlerContext ctx) { FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, NOT_MODIFIED); setDateHeader(response); // Close the connection as soon as the error message is sent. ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); }
@Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable t) { Channel ch = ctx.channel(); // Prevent recursion when the client close the connection during a write operation. In that // scenario the sendError will be invoked, but will fail since the channel has already been closed // For an unknown reason, if (ch.attr(ATTACHMENT) != null && Error.class.isAssignableFrom(ch.attr(ATTACHMENT).get().getClass())) { return; } Throwable cause = t.getCause(); if (cause instanceof TooLongFrameException) { sendError(ctx, BAD_REQUEST, null); return; } ch.attr(ATTACHMENT).set(new Error()); if (ch.isOpen()) { sendError(ctx, INTERNAL_SERVER_ERROR, null); } if (ctx.channel().isActive()) { sendError(ctx, INTERNAL_SERVER_ERROR, null); } }
@Override public void sendError(ChannelHandlerContext ctx, HttpResponseStatus status, FullHttpRequest e) { // For websocket, we can't send an error logger.trace("Error {} for {}", status, e); if (websocketChannels.contains(ctx.channel())) { logger.debug("Error {} for {}", status, e); ctx.channel().close().addListener(ChannelFutureListener.CLOSE); } else if (e != null) { if (HttpHeaders.getHeader(e, STATIC_MAPPING, "false").equalsIgnoreCase("false")) { super.sendError(ctx, status, e); } } else { super.sendError(ctx, status, e); } }