EchoServer:
public class EchoServer {
static final boolean SSL = System.getProperty("ssl") != null;
static final int PORT = Integer.parseInt(System.getProperty("port", "8007"));
public static void main(String[] args) throws Exception {
final SslContext sslCtx;
if (SSL) {
SelfSignedCertificate ssc = new SelfSignedCertificate();
sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey());
} else {
sslCtx = null;
}
ServerBootstrap bootstrap = new ServerBootstrap(
new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@Override
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline p = Channels.pipeline();
if (sslCtx != null) {
p.addLast("ssl", sslCtx.newHandler());
}
p.addLast("http-message-converter", new HttpRequestConverterHandler());
p.addLast("echo", new EchoHandler());
p.addLast("http", new HttpHandler());
return p;
}
});
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("child.receiveBufferSize", 1048576);
bootstrap.setOption("child.sendBufferSize", 1048576);
bootstrap.bind(new InetSocketAddress(PORT));
}
}
HttpRequestConverterHandler:
public class HttpRequestConverterHandler extends SimpleChannelUpstreamHandler {
protected StringBuilder httpMessage(Channel channel, String url0) throws MalformedURLException {
URL url = new URL(url0);
String host = url.getHost();
int port = url.getPort();
String path = url.getPath();
System.out.println("host: " + host + ", port: " + port + ", path: " + path);
channel.setAttachment(new HttpHost(host, port));
StringBuilder sb = new StringBuilder();
sb.append("GET " + path + " HTTP/1.1\r\n");
sb.append("Host:" + host + (port == -1 ? "" : String.valueOf(port)) + "\r\n");
sb.append("\r\n");
return sb;
}
/**
* pass a url as a message event
*/
@Override
public void messageReceived(ChannelHandlerContext ctx, final MessageEvent e) throws Exception {
ChannelBuffer buf = (ChannelBuffer) e.getMessage();
byte[] data = new byte[buf.readableBytes()];
buf.getBytes(buf.readerIndex(), data);
String msg = new String(data);
System.out.println(msg);
StringBuilder sb = httpMessage(e.getChannel(), msg);
ChannelBufferFactory channelBufferFactory = HeapChannelBufferFactory.getInstance();
ChannelBuffer nb = channelBufferFactory.getBuffer(sb.length());
nb.writeBytes(sb.toString().getBytes("utf-8"));
ctx.sendUpstream(new UpstreamMessageEvent(e.getChannel(), nb, e.getRemoteAddress()));
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
// Close the connection when an exception is raised.
e.getCause().printStackTrace();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write("invalid url.".getBytes("utf-8"));
ChannelBufferFactory channelBufferFactory = HeapChannelBufferFactory.getInstance();
ChannelBuffer nb = channelBufferFactory.getBuffer(bos.size());
nb.writeBytes(bos.toByteArray());
e.getChannel().write(nb);
e.getChannel().close();
}
}
HttpHost:
public class HttpHost {
private String host;
private int port;
public HttpHost(String host) {
this(host, -1);
}
public HttpHost(String host, int port) {
this.host = host;
this.port = port;
}
public String getHost() {
return host;
}
public int getPort() {
return port;
}
}
EchoHandler:
public class EchoHandler extends SimpleChannelUpstreamHandler {
private final AtomicLong transferredBytes = new AtomicLong();
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
// Send back the received message to the remote peer.
transferredBytes.addAndGet(((ChannelBuffer) e.getMessage()).readableBytes());
ChannelBuffer buf = (ChannelBuffer) e.getMessage();
if (ctx.canHandleUpstream()) {
ctx.sendUpstream(new UpstreamMessageEvent(e.getChannel(), e.getMessage(), e.getRemoteAddress()));
} else {
e.getChannel().write(buf);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
// Close the connection when an exception is raised.
e.getCause().printStackTrace();
e.getChannel().close();
}
}
HttpHandler:
public class HttpHandler extends SimpleChannelUpstreamHandler {
public String execute(String host, int port, String msg) {
port = port == -1 ? 80 : port;
System.out.println("host: " + host);
System.out.println("port: " + port);
System.out.println("msg: " + msg);
try {
Socket socket = new Socket(host, port);
OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream());
writer.write(msg);
writer.flush();
InputStream is = socket.getInputStream();
StringBuilder sb = new StringBuilder();
byte[] b = new byte[512];
int nb = -1;
while ((nb = is.read(b)) != -1) {
sb.append(new String(b, 0, nb));
}
System.out.println(sb.toString());
return sb.toString();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
/**
* pass a url as a message event
*/
@Override
public void messageReceived(ChannelHandlerContext ctx, final MessageEvent e) throws Exception {
ChannelBuffer buf = (ChannelBuffer) e.getMessage();
byte[] data = new byte[buf.readableBytes()];
buf.getBytes(buf.readerIndex(), data);
String msg = new String(data);
HttpHost host = (HttpHost) e.getChannel().getAttachment();
String result = execute(host.getHost(), host.getPort(), msg);
byte[] bytes = result.getBytes("utf-8");
ChannelBufferFactory channelBufferFactory = HeapChannelBufferFactory.getInstance();
ChannelBuffer nb = channelBufferFactory.getBuffer(data.length + bytes.length);
nb.writeBytes(data);
nb.writeBytes(bytes);
e.getChannel().write(nb);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
// Close the connection when an exception is raised.
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write("invalid http request.".getBytes("utf-8"));
ChannelBufferFactory channelBufferFactory = HeapChannelBufferFactory.getInstance();
ChannelBuffer nb = channelBufferFactory.getBuffer(bos.size());
nb.writeBytes(bos.toByteArray());
e.getChannel().write(nb);
e.getChannel().close();
}
}
[c:\~]$ telnet localhost 8007
Host 'localhost' resolved to 127.0.0.1.
Connecting to 127.0.0.1:8007...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
invalid url.
Connection closed by foreign host.
Disconnected from remote host(localhost:8007) at 14:19:07.
Type `help' to learn how to use Xshell prompt.
[c:\~]$ telnet localhost 8007
Host 'localhost' resolved to 127.0.0.1.
Connecting to 127.0.0.1:8007...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
http://www.cnblogs.com/zhang-qiang/articles/2050885.html
GET /zhang-qiang/articles/2050885.html HTTP/1.1
Host:www.cnblogs.com
HTTP/1.1 200 OK
Date: Sun, 18 Sep 2016 07:15:25 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 17071
Connection: keep-alive
Vary: Accept-Encoding
Cache-Control: private, max-age=10
Expires: Sun, 18 Sep 2016 07:15:33 GMT
Last-Modified: Sun, 18 Sep 2016 07:15:23 GMT
X-UA-Compatible: IE=10
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-cn">
<head>