package com.test.server;
import static org.jboss.netty.handler.codec.http.HttpHeaders.is100ContinueExpected;
import static org.jboss.netty.handler.codec.http.HttpHeaders.isKeepAlive;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.COOKIE;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.SET_COOKIE;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.CONTINUE;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.OK;
import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1;
import java.io.File;
import java.io.RandomAccessFile;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.handler.codec.http.*;
import org.jboss.netty.handler.stream.ChunkedFile;
import org.jboss.netty.util.CharsetUtil;
public class HttpRequestHandler extends SimpleChannelUpstreamHandler {
private HttpRequest request;
private boolean readingChunks;
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
if (!readingChunks) {
HttpRequest request = this.request = (HttpRequest) e.getMessage();
String uri = request.getUri();
System.out.println("-----------------------------------------------------------------");
System.out.println("uri:"+uri);
System.out.println("-----------------------------------------------------------------");
/**
* 100 Continue
* 是这样的一种情况:HTTP客户端程序有一个实体的主体部分要发送给服务器,但希望在发送之前查看下服务器是否会
* 接受这个实体,所以在发送实体之前先发送了一个携带100
* Continue的Expect请求首部的请求。服务器在收到这样的请求后,应该用 100 Continue或一条错误码来进行响应。
*/
if (is100ContinueExpected(request)) {
send100Continue(e);
}
// 解析http头部
for (Map.Entry<String, String> h : request.getHeaders()) {
System.out.println("HEADER: " + h.getKey() + " = " + h.getValue() + "\r\n");
}
// 解析请求参数
QueryStringDecoder queryStringDecoder = new QueryStringDecoder(request.getUri());
Map<String, List<String>> params = queryStringDecoder.getParameters();
if (!params.isEmpty()) {
for (Entry<String, List<String>> p : params.entrySet()) {
String key = p.getKey();
List<String> vals = p.getValue();
for (String val : vals) {
System.out.println("PARAM: " + key + " = " + val + "\r\n");
}
}
}
if (request.isChunked()) {
readingChunks = true;
} else {
ChannelBuffer content = request.getContent();
if (content.readable()) {
System.out.println(content.toString(CharsetUtil.UTF_8));
}
writeResponse(e, uri);
}
} else {// 为分块编码时
HttpChunk chunk = (HttpChunk) e.getMessage();
if (chunk.isLast()) {
readingChunks = false;
// END OF CONTENT\r\n"
HttpChunkTrailer trailer = (HttpChunkTrailer) chunk;
if (!trailer.getHeaderNames().isEmpty()) {
for (String name : trailer.getHeaderNames()) {
for (String value : trailer.getHeaders(name)) {
System.out.println("TRAILING HEADER: " + name + " = " + value + "\r\n");
}
}
}
writeResponse(e, "/");
} else {
System.out.println("CHUNK: " + chunk.getContent().toString(CharsetUtil.UTF_8)
+ "\r\n");
}
}
}
private void writeResponse(MessageEvent e, String uri) {
// 解析Connection首部,判断是否为持久连接
boolean keepAlive = isKeepAlive(request);
// Build the response object.
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
response.setStatus(HttpResponseStatus.OK);
// 服务端可以通过location首部将客户端导向某个资源的地址。
// response.addHeader("Location", uri);
if (keepAlive) {
// Add 'Content-Length' header only for a keep-alive connection.
response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes());
}
// 得到客户端的cookie信息,并再次写到客户端
String cookieString = request.getHeader(COOKIE);
if (cookieString != null) {
CookieDecoder cookieDecoder = new CookieDecoder();
Set<Cookie> cookies = cookieDecoder.decode(cookieString);
if (!cookies.isEmpty()) {
CookieEncoder cookieEncoder = new CookieEncoder(true);
for (Cookie cookie : cookies) {
cookieEncoder.addCookie(cookie);
}
response.addHeader(SET_COOKIE, cookieEncoder.encode());
}
}
final String path = "c:\\github.jpg";
File localFile = new File(path);
// 如果文件隐藏或者不存在
if (localFile.isHidden() || !localFile.exists()) {
// 逻辑处理
return;
}
// 如果请求路径为目录
if (localFile.isDirectory()) {
// 逻辑处理
return;
}
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(localFile, "r");
long fileLength = raf.length();
response.setHeader(HttpHeaders.Names.CONTENT_LENGTH, String.valueOf(fileLength));
Channel ch = e.getChannel();
ch.write(response);
// 这里又要重新温习下http的方法,head方法与get方法类似,但是服务器在响应中只返回首部,不会返回实体的主体部分
if (!request.getMethod().equals(HttpMethod.HEAD)) {
ch.write(new ChunkedFile(raf, 0, fileLength, 8192));//8kb
}
} catch (Exception e2) {
e2.printStackTrace();
} finally {
if (keepAlive) {
response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes());
}
if (!keepAlive) {
e.getFuture().addListener(ChannelFutureListener.CLOSE);
}
}
}
private void send100Continue(MessageEvent e) {
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, CONTINUE);
e.getChannel().write(response);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
e.getCause().printStackTrace();
e.getChannel().close();
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
testnetty3.rar (14个子文件)
testnetty3
bin
com
test
server
HttpChunkedServerPipelineFactory.class 1KB
HttpChunkedServer.class 2KB
HttpRequestHandler.class 9KB
HttpChunkedServer$1.class 1KB
HttpChunkedServerHandler.class 6KB
.settings
org.eclipse.wst.common.project.facet.core.xml 122B
org.eclipse.jdt.core.prefs 598B
src
com
test
server
HttpChunkedServer.java 2KB
HttpChunkedServerHandler.java 4KB
HttpRequestHandler.java 8KB
HttpChunkedServerPipelineFactory.java 941B
.project 592B
.classpath 487B
lib
netty-3.6.5.Final.jar 1.15MB
共 14 条
- 1
资源评论
- xukaide772017-08-17骗分的,cao蛋,没有用websocket协议
昵称不知道写啥
- 粉丝: 1
- 资源: 8
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功