@Override public void messageReceived( ChannelHandlerContext ctx, MessageEvent e ) throws Exception { HttpRequest request = (HttpRequest)e.getMessage( ) ; if( request.getMethod( ) != GET ) { sendError( ctx, FORBIDDEN ) ; return ; } final String path = sanitizeUri( request.getUri( ) ) ; if( path == null ) { sendError( ctx, FORBIDDEN ) ; return ; } File file = new File(path) ; if( file.isHidden( ) || !file.exists( ) ) { sendError( ctx, NOT_FOUND ) ; return ; } RandomAccessFile raf ; try { raf = new RandomAccessFile( file, "r" ) ; } catch( FileNotFoundException fnfe ) { sendError( ctx, NOT_FOUND ) ; return; } long fileLength = raf.length( ) ; HttpResponse response = new DefaultHttpResponse( HTTP_1_1, OK ) ; setContentLength( response, fileLength ) ; Channel ch = e.getChannel( ) ; //Escreve a linha inicial do cabe�alho ch.write( response ) ; // Escreve o conte�do ChannelFuture writeFuture ; if( ch.getPipeline( ).get( SslHandler.class ) != null ) { writeFuture = ch.write( new ChunkedFile( raf, 0, fileLength, 8192 ) ) ; } else { final FileRegion region = new DefaultFileRegion( raf.getChannel( ), 0, fileLength ) ; writeFuture = ch.write( region ) ; writeFuture.addListener( new ChannelFutureProgressListener( ) { @Override public void operationComplete( ChannelFuture arg0 ) throws Exception { region.releaseExternalResources( ) ; } @Override public void operationProgressed( ChannelFuture future, long amount, long current, long total ) throws Exception { System.out.printf( "%s: %d / %d (+%d)%n", path, current, total, amount ); } }) ; } // Decide se fecha a conex�o ou n�o!! if( !isKeepAlive( request ) ) { writeFuture.addListener( ChannelFutureListener.CLOSE ) ; } }