@Override
	protected void channelRead0(final ChannelHandlerContext ctx, HttpRequest request) throws Exception {
		
		QueryStringDecoder decoder = new QueryStringDecoder(request.getUri());
		String decodedUri = decoder.path();
		
		statCollector.addProcessedConnection(ctx.channel(), ConnectionParameter.URI, decodedUri);
		
		//	response Hello world
		if(decodedUri.equals(HELLO_REQUEST)){

			HttpResponse response = new DefaultFullHttpResponse(
					HttpVersion.HTTP_1_1,
					HttpResponseStatus.OK,
					packString(ctx, HELLO_RESPONSE));
//			ctx.write(response).addListener(ChannelFutureListener.CLOSE);
			new DelayedResponse(ctx, response, 10000);
		}
		
		//	redirect
		else if(decodedUri.equals(REDIRECT_REQUEST)){
			List<String> redirectUrlList = decoder.parameters().get("url");
			String redirectUrl = null;
			if(redirectUrlList != null && redirectUrlList.size() > 0){
				redirectUrl = "http://" + redirectUrlList.get(0);
			}
			statCollector.addRedirect(redirectUrl);

			HttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.MOVED_PERMANENTLY);
			HttpHeaders.setHeader(response, "Location", redirectUrl);
			
			ctx.write(response).addListener(ChannelFutureListener.CLOSE);
		}
		
		//	status table	
		else if(decodedUri.equals(STAT_REQUEST)){
			
			String statTableString = new StatFormatter().formatHTMLTable(statCollector);
			HttpResponse response = new DefaultFullHttpResponse(
					HttpVersion.HTTP_1_1,
					HttpResponseStatus.OK,
					packString(ctx, statTableString));
			
			ctx.write(response).addListener(ChannelFutureListener.CLOSE);
		}
		
		//	default
		else {
			ctx.close();
		}
	}