Merged the HTTP branch into the trunk
This commit is contained in:
parent
e29ba2eed5
commit
4ac032c657
@ -6,6 +6,7 @@ sent to Trustin Lee <tlee@redhat.com>.
|
|||||||
|
|
||||||
SVN Login(s) Name
|
SVN Login(s) Name
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
ataylor Andy Taylor
|
||||||
trustin Trustin Heuiseung Lee
|
trustin Trustin Heuiseung Lee
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
92
src/main/java/org/jboss/netty/example/http/HttpClient.java
Normal file
92
src/main/java/org/jboss/netty/example/http/HttpClient.java
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.example.http;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
import org.jboss.netty.bootstrap.ClientBootstrap;
|
||||||
|
import org.jboss.netty.buffer.ChannelBuffer;
|
||||||
|
import org.jboss.netty.buffer.ChannelBuffers;
|
||||||
|
import org.jboss.netty.channel.Channel;
|
||||||
|
import org.jboss.netty.channel.ChannelFactory;
|
||||||
|
import org.jboss.netty.channel.ChannelFuture;
|
||||||
|
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
|
||||||
|
import org.jboss.netty.handler.codec.http.DefaultHttpRequest;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpHeaders;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpMethod;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpRequest;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpVersion;
|
||||||
|
import org.jboss.netty.handler.codec.http.QueryStringEncoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
*/
|
||||||
|
public class HttpClient {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
// Parse options.
|
||||||
|
String host = "localhost";
|
||||||
|
int port = 8080;
|
||||||
|
|
||||||
|
// Configure the client.
|
||||||
|
ChannelFactory factory =
|
||||||
|
new NioClientSocketChannelFactory(
|
||||||
|
Executors.newCachedThreadPool(),
|
||||||
|
Executors.newCachedThreadPool());
|
||||||
|
|
||||||
|
ClientBootstrap bootstrap = new ClientBootstrap(factory);
|
||||||
|
HttpPipelineFactory handler = new HttpPipelineFactory(new HttpResponseHandler());
|
||||||
|
bootstrap.setPipelineFactory(handler);
|
||||||
|
bootstrap.setOption("tcpNoDelay", true);
|
||||||
|
bootstrap.setOption("keepAlive", true);
|
||||||
|
// Start the connection attempt.
|
||||||
|
ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));
|
||||||
|
|
||||||
|
// Wait until the connection attempt succeeds or fails.
|
||||||
|
Channel channel = future.awaitUninterruptibly().getChannel();
|
||||||
|
if (!future.isSuccess()) {
|
||||||
|
future.getCause().printStackTrace();
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
String message = "It's Hello From me";
|
||||||
|
ChannelBuffer buf = ChannelBuffers.wrappedBuffer(message.getBytes());
|
||||||
|
HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_0, HttpMethod.GET, new URI("/netty/"));
|
||||||
|
request.addHeader(HttpHeaders.HOST, host);
|
||||||
|
request.addHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(buf.writerIndex()));
|
||||||
|
request.setContent(buf);
|
||||||
|
ChannelFuture lastWriteFuture = channel.write(request);
|
||||||
|
buf = ChannelBuffers.wrappedBuffer(message.getBytes());
|
||||||
|
QueryStringEncoder queryStringEncoder = new QueryStringEncoder("/netty/");
|
||||||
|
queryStringEncoder.addParam("testparam", "hey ho");
|
||||||
|
queryStringEncoder.addParam("testparam2", "hey ho again");
|
||||||
|
request = new DefaultHttpRequest(HttpVersion.HTTP_1_0, HttpMethod.GET, queryStringEncoder.toUri());
|
||||||
|
request.addHeader(HttpHeaders.HOST, host);
|
||||||
|
request.addHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(buf.writerIndex()));
|
||||||
|
request.setContent(buf);
|
||||||
|
lastWriteFuture = channel.write(request);
|
||||||
|
lastWriteFuture.awaitUninterruptibly();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.example.http;
|
||||||
|
|
||||||
|
import static org.jboss.netty.channel.Channels.*;
|
||||||
|
|
||||||
|
import org.jboss.netty.channel.ChannelHandler;
|
||||||
|
import org.jboss.netty.channel.ChannelPipeline;
|
||||||
|
import org.jboss.netty.channel.ChannelPipelineFactory;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpRequestEncoder;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpResponseDecoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
*/
|
||||||
|
public class HttpPipelineFactory implements ChannelPipelineFactory {
|
||||||
|
private final ChannelHandler handler;
|
||||||
|
|
||||||
|
public HttpPipelineFactory(HttpResponseHandler handler) {
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelPipeline getPipeline() throws Exception {
|
||||||
|
// Create a default pipeline implementation.
|
||||||
|
ChannelPipeline pipeline = pipeline();
|
||||||
|
pipeline.addLast("decoder", new HttpResponseDecoder());
|
||||||
|
pipeline.addLast("encoder", new HttpRequestEncoder());
|
||||||
|
pipeline.addLast("handler", handler);
|
||||||
|
return pipeline;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.example.http;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jboss.netty.buffer.ChannelBuffer;
|
||||||
|
import org.jboss.netty.buffer.ChannelBuffers;
|
||||||
|
import org.jboss.netty.channel.ChannelHandlerContext;
|
||||||
|
import org.jboss.netty.channel.ChannelPipelineCoverage;
|
||||||
|
import org.jboss.netty.channel.MessageEvent;
|
||||||
|
import org.jboss.netty.channel.SimpleChannelHandler;
|
||||||
|
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpHeaders;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpRequest;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpResponse;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpVersion;
|
||||||
|
import org.jboss.netty.handler.codec.http.QueryStringDecoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
*/
|
||||||
|
@ChannelPipelineCoverage("all")
|
||||||
|
public class HttpRequestHandler extends SimpleChannelHandler {
|
||||||
|
@Override
|
||||||
|
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
|
||||||
|
HttpRequest request = (HttpRequest) e.getMessage();
|
||||||
|
System.out.println(request.getContent().toString(Charset.defaultCharset().name()));
|
||||||
|
QueryStringDecoder queryStringDecoder = new QueryStringDecoder(request.getURI());
|
||||||
|
Map<String, List<String>> params = queryStringDecoder.getParameters();
|
||||||
|
for (String key : params.keySet()) {
|
||||||
|
List<String> vals = params.get(key);
|
||||||
|
for (String val : vals) {
|
||||||
|
System.out.println("param: " + key + "=" + val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
|
||||||
|
String message = "and its hello from me";
|
||||||
|
ChannelBuffer buf = ChannelBuffers.wrappedBuffer(message.getBytes());
|
||||||
|
response.setContent(buf);
|
||||||
|
response.addHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(buf.writerIndex()));
|
||||||
|
e.getChannel().write(response);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.example.http;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
import org.jboss.netty.channel.ChannelHandlerContext;
|
||||||
|
import org.jboss.netty.channel.ChannelPipelineCoverage;
|
||||||
|
import org.jboss.netty.channel.MessageEvent;
|
||||||
|
import org.jboss.netty.channel.SimpleChannelHandler;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
*/
|
||||||
|
@ChannelPipelineCoverage("all")
|
||||||
|
public class HttpResponseHandler extends SimpleChannelHandler {
|
||||||
|
@Override
|
||||||
|
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
|
||||||
|
HttpResponse response = (HttpResponse) e.getMessage();
|
||||||
|
System.out.println(response.getContent().toString(Charset.defaultCharset().name()));
|
||||||
|
}
|
||||||
|
}
|
52
src/main/java/org/jboss/netty/example/http/HttpServer.java
Normal file
52
src/main/java/org/jboss/netty/example/http/HttpServer.java
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.example.http;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
import org.jboss.netty.bootstrap.ServerBootstrap;
|
||||||
|
import org.jboss.netty.channel.ChannelFactory;
|
||||||
|
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
*/
|
||||||
|
public class HttpServer {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// Configure the server.
|
||||||
|
ChannelFactory factory =
|
||||||
|
new NioServerSocketChannelFactory(
|
||||||
|
Executors.newCachedThreadPool(),
|
||||||
|
Executors.newCachedThreadPool());
|
||||||
|
|
||||||
|
ServerBootstrap bootstrap = new ServerBootstrap(factory);
|
||||||
|
HttpServerPipelineFactory pipeline = new HttpServerPipelineFactory(new HttpRequestHandler());
|
||||||
|
bootstrap.setPipelineFactory(pipeline);
|
||||||
|
bootstrap.setOption("child.tcpNoDelay", true);
|
||||||
|
bootstrap.setOption("child.keepAlive", true);
|
||||||
|
|
||||||
|
// Bind and start to accept incoming connections.
|
||||||
|
bootstrap.bind(new InetSocketAddress(8080));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.example.http;
|
||||||
|
|
||||||
|
import static org.jboss.netty.channel.Channels.*;
|
||||||
|
|
||||||
|
import org.jboss.netty.channel.ChannelHandler;
|
||||||
|
import org.jboss.netty.channel.ChannelPipeline;
|
||||||
|
import org.jboss.netty.channel.ChannelPipelineFactory;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
*/
|
||||||
|
public class HttpServerPipelineFactory implements ChannelPipelineFactory {
|
||||||
|
private final ChannelHandler handler;
|
||||||
|
|
||||||
|
public HttpServerPipelineFactory(HttpRequestHandler handler) {
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelPipeline getPipeline() throws Exception {
|
||||||
|
// Create a default pipeline implementation.
|
||||||
|
ChannelPipeline pipeline = pipeline();
|
||||||
|
pipeline.addLast("decoder", new HttpRequestDecoder());
|
||||||
|
pipeline.addLast("encoder", new HttpResponseEncoder());
|
||||||
|
pipeline.addLast("handler", handler);
|
||||||
|
return pipeline;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.example.http;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
import org.jboss.netty.bootstrap.ClientBootstrap;
|
||||||
|
import org.jboss.netty.channel.Channel;
|
||||||
|
import org.jboss.netty.channel.ChannelFactory;
|
||||||
|
import org.jboss.netty.channel.ChannelFuture;
|
||||||
|
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
|
||||||
|
import org.jboss.netty.handler.codec.http.DefaultHttpRequest;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpHeaders;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpMethod;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpRequest;
|
||||||
|
import org.jboss.netty.handler.codec.http.HttpVersion;
|
||||||
|
import org.jboss.netty.handler.codec.http.QueryStringEncoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
*/
|
||||||
|
public class HttpWebserverClient {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
// Parse options.
|
||||||
|
String host = "www.jboss.org";
|
||||||
|
int port = 80;
|
||||||
|
|
||||||
|
// Configure the client.
|
||||||
|
ChannelFactory factory =
|
||||||
|
new NioClientSocketChannelFactory(
|
||||||
|
Executors.newCachedThreadPool(),
|
||||||
|
Executors.newCachedThreadPool());
|
||||||
|
|
||||||
|
ClientBootstrap bootstrap = new ClientBootstrap(factory);
|
||||||
|
HttpPipelineFactory handler = new HttpPipelineFactory(new HttpResponseHandler());
|
||||||
|
bootstrap.setPipelineFactory(handler);
|
||||||
|
// Start the connection attempt.
|
||||||
|
ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));
|
||||||
|
|
||||||
|
// Wait until the connection attempt succeeds or fails.
|
||||||
|
Channel channel = future.awaitUninterruptibly().getChannel();
|
||||||
|
if (!future.isSuccess()) {
|
||||||
|
future.getCause().printStackTrace();
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
QueryStringEncoder uriBuilder = new QueryStringEncoder("/netty/");
|
||||||
|
HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_0, HttpMethod.GET, uriBuilder.toUri());
|
||||||
|
request.addHeader(HttpHeaders.HOST, host);
|
||||||
|
ChannelFuture lastWriteFuture = channel.write(request);
|
||||||
|
lastWriteFuture.awaitUninterruptibly();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import org.jboss.netty.buffer.ChannelBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a default Http Message which holds the headers and body.
|
||||||
|
*
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
* @author Trustin Lee (tlee@redhat.com)
|
||||||
|
*/
|
||||||
|
public class DefaultHttpMessage implements HttpMessage {
|
||||||
|
private final static Comparator<String> caseIgnoringComparator = new CaseIgnoringComparator();
|
||||||
|
|
||||||
|
Map<String, List<String>> headers = new TreeMap<String, List<String>>(caseIgnoringComparator);
|
||||||
|
|
||||||
|
private final HttpVersion version;
|
||||||
|
|
||||||
|
private ChannelBuffer content;
|
||||||
|
|
||||||
|
protected DefaultHttpMessage(final HttpVersion version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addHeader(final String name, final String value) {
|
||||||
|
if (value == null) {
|
||||||
|
throw new NullPointerException("value is null");
|
||||||
|
}
|
||||||
|
if (headers.get(name) == null) {
|
||||||
|
headers.put(name, new ArrayList<String>());
|
||||||
|
}
|
||||||
|
headers.get(name).add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeader(final String name, final List<String> values) {
|
||||||
|
if (values == null || values.size() == 0) {
|
||||||
|
throw new NullPointerException("no values present");
|
||||||
|
}
|
||||||
|
headers.put(name, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getContentLength() {
|
||||||
|
List<String> contentLength = headers.get(HttpHeaders.CONTENT_LENGTH);
|
||||||
|
if (contentLength != null && contentLength.size() > 0) {
|
||||||
|
return Integer.valueOf(contentLength.get(0));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isChunked() {
|
||||||
|
List<String> chunked = headers.get(HttpHeaders.TRANSFER_ENCODING.KEY);
|
||||||
|
return chunked != null && chunked.size() > 0 && chunked.get(0).equalsIgnoreCase(HttpHeaders.TRANSFER_ENCODING.CHUNKED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearHeaders() {
|
||||||
|
headers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(final ChannelBuffer content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHeader(final String name) {
|
||||||
|
List<String> header = headers.get(name);
|
||||||
|
return header != null && header.size() > 0 ? headers.get(name).get(0) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getHeaders(final String name) {
|
||||||
|
return headers.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsHeader(final String name) {
|
||||||
|
return headers.containsKey(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getHeaderNames() {
|
||||||
|
return headers.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpVersion getProtocolVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelBuffer getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class CaseIgnoringComparator implements Comparator<String> {
|
||||||
|
|
||||||
|
CaseIgnoringComparator() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compare(String o1, String o2) {
|
||||||
|
return o1.compareToIgnoreCase(o2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An http request implementation
|
||||||
|
*
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
* @author Trustin Lee (tlee@redhat.com)
|
||||||
|
*/
|
||||||
|
public class DefaultHttpRequest extends DefaultHttpMessage implements HttpRequest {
|
||||||
|
|
||||||
|
private final HttpMethod method;
|
||||||
|
|
||||||
|
private final URI uri;
|
||||||
|
|
||||||
|
public DefaultHttpRequest(HttpVersion httpVersion, HttpMethod method, URI uri) {
|
||||||
|
super(httpVersion);
|
||||||
|
this.method = method;
|
||||||
|
this.uri = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpMethod getMethod() {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public URI getURI() {
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isKeepAlive() {
|
||||||
|
//todo
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* an http response implementation
|
||||||
|
*
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
* @author Trustin Lee (tlee@redhat.com)
|
||||||
|
*/
|
||||||
|
public class DefaultHttpResponse extends DefaultHttpMessage implements HttpResponse {
|
||||||
|
private final HttpResponseStatus status;
|
||||||
|
|
||||||
|
public DefaultHttpResponse(HttpVersion version, HttpResponseStatus status) {
|
||||||
|
super(version);
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpResponseStatus getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
*/
|
||||||
|
public class HttpCodecUtil {
|
||||||
|
//space ' '
|
||||||
|
public static final byte SP = 32;
|
||||||
|
|
||||||
|
//tab ' '
|
||||||
|
public static final byte HT = 9;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Carriage return
|
||||||
|
*/
|
||||||
|
public static final byte CR = 13;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Equals '='
|
||||||
|
*/
|
||||||
|
public static final byte EQUALS = 61;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Line feed character
|
||||||
|
*/
|
||||||
|
public static final byte LF = 10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* carriage return line feed
|
||||||
|
*/
|
||||||
|
public static final byte[] CRLF = new byte[] { CR, LF };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Colon ':'
|
||||||
|
*/
|
||||||
|
public static final byte COLON = 58;
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
*/
|
||||||
|
public class HttpHeaders {
|
||||||
|
public static final String HOST = "Host";
|
||||||
|
|
||||||
|
public static final String CONTENT_LENGTH = "Content-Length";
|
||||||
|
|
||||||
|
public static final class CONNECTION {
|
||||||
|
public static final String KEY = "Connection";
|
||||||
|
|
||||||
|
public static final String CLOSE = "Close";
|
||||||
|
|
||||||
|
public static final String KEEP_ALIVE = "Keep-alive";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class TRANSFER_ENCODING {
|
||||||
|
public static final String KEY = "Transfer-Encoding";
|
||||||
|
|
||||||
|
public static final String CHUNKED = "Chunked";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jboss.netty.buffer.ChannelBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulates an Http message. this will contain the protocol version, headers and the body of a message
|
||||||
|
*
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
* @author Trustin Lee (tlee@redhat.com)
|
||||||
|
*/
|
||||||
|
public interface HttpMessage {
|
||||||
|
String getHeader(String name);
|
||||||
|
|
||||||
|
List<String> getHeaders(String name);
|
||||||
|
|
||||||
|
boolean containsHeader(String name);
|
||||||
|
|
||||||
|
Set<String> getHeaderNames();
|
||||||
|
|
||||||
|
HttpVersion getProtocolVersion();
|
||||||
|
|
||||||
|
ChannelBuffer getContent();
|
||||||
|
|
||||||
|
void addHeader(String name, String value);
|
||||||
|
|
||||||
|
void setHeader(String name, List<String> values);
|
||||||
|
|
||||||
|
int getContentLength();
|
||||||
|
|
||||||
|
void setContent(ChannelBuffer content);
|
||||||
|
|
||||||
|
boolean isChunked();
|
||||||
|
|
||||||
|
void clearHeaders();
|
||||||
|
}
|
@ -0,0 +1,221 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jboss.netty.buffer.ChannelBuffer;
|
||||||
|
import org.jboss.netty.buffer.ChannelBuffers;
|
||||||
|
import org.jboss.netty.channel.Channel;
|
||||||
|
import org.jboss.netty.channel.ChannelHandlerContext;
|
||||||
|
import org.jboss.netty.handler.codec.replay.ReplayingDecoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes an Http type message.
|
||||||
|
*
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
* @author Trustin Lee (tlee@redhat.com)
|
||||||
|
*/
|
||||||
|
public abstract class HttpMessageDecoder extends ReplayingDecoder<HttpMessageDecoder.ResponseState> {
|
||||||
|
protected HttpMessage message;
|
||||||
|
|
||||||
|
private ChannelBuffer content;
|
||||||
|
|
||||||
|
private int chunkSize;
|
||||||
|
|
||||||
|
public enum ResponseState {
|
||||||
|
READ_INITIAL,
|
||||||
|
READ_HEADER,
|
||||||
|
READ_CONTENT,
|
||||||
|
READ_FIXED_LENGTH_CONTENT,
|
||||||
|
READ_CHUNK_SIZE,
|
||||||
|
READ_CHUNKED_CONTENT,
|
||||||
|
READ_CRLF,;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResponseState nextState;
|
||||||
|
|
||||||
|
protected HttpMessageDecoder() {
|
||||||
|
super(ResponseState.READ_INITIAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, ResponseState state) throws Exception {
|
||||||
|
switch (state) {
|
||||||
|
case READ_INITIAL: {
|
||||||
|
readInitial(buffer);
|
||||||
|
}
|
||||||
|
case READ_HEADER: {
|
||||||
|
readHeaders(buffer);
|
||||||
|
//we return null here, this forces decode to be called again where we will decode the content
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
case READ_CONTENT: {
|
||||||
|
if (content == null) {
|
||||||
|
content = ChannelBuffers.dynamicBuffer();
|
||||||
|
}
|
||||||
|
//this will cause a replay error until the channel is closed where this will read whats left in the buffer
|
||||||
|
content.writeBytes(buffer.readBytes(buffer.readableBytes()));
|
||||||
|
return reset();
|
||||||
|
}
|
||||||
|
case READ_FIXED_LENGTH_CONTENT: {
|
||||||
|
//we have a content-length so we just read the correct number of bytes
|
||||||
|
readFixedLengthContent(buffer);
|
||||||
|
return reset();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* everything else after this point takes care of reading chunked content. basically, read chunk size,
|
||||||
|
* read chunk, read and ignore the CRLF and repeat until 0
|
||||||
|
*/
|
||||||
|
case READ_CHUNK_SIZE: {
|
||||||
|
String line = readIntoCurrentLine(buffer);
|
||||||
|
|
||||||
|
chunkSize = getChunkSize(line);
|
||||||
|
if (chunkSize == 0) {
|
||||||
|
byte next = buffer.readByte();
|
||||||
|
if (next == HttpCodecUtil.CR) {
|
||||||
|
buffer.readByte();
|
||||||
|
}
|
||||||
|
return reset();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
checkpoint(ResponseState.READ_CHUNKED_CONTENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case READ_CHUNKED_CONTENT: {
|
||||||
|
readChunkedContent(buffer);
|
||||||
|
}
|
||||||
|
case READ_CRLF: {
|
||||||
|
byte next = buffer.readByte();
|
||||||
|
if (next == HttpCodecUtil.CR) {
|
||||||
|
buffer.readByte();
|
||||||
|
}
|
||||||
|
checkpoint(nextState);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw new Error("Shouldn't reach here.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object reset() {
|
||||||
|
message.setContent(content);
|
||||||
|
content = null;
|
||||||
|
nextState = null;
|
||||||
|
checkpoint(ResponseState.READ_INITIAL);
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readChunkedContent(ChannelBuffer buffer) {
|
||||||
|
if (content == null) {
|
||||||
|
content = ChannelBuffers.dynamicBuffer(chunkSize);
|
||||||
|
}
|
||||||
|
content.writeBytes(buffer, chunkSize);
|
||||||
|
nextState = ResponseState.READ_CHUNK_SIZE;
|
||||||
|
checkpoint(ResponseState.READ_CRLF);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readFixedLengthContent(ChannelBuffer buffer) {
|
||||||
|
int length = message.getContentLength();
|
||||||
|
if (content == null) {
|
||||||
|
content = ChannelBuffers.buffer(length);
|
||||||
|
}
|
||||||
|
content.writeBytes(buffer.readBytes(length));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readHeaders(ChannelBuffer buffer) {
|
||||||
|
message.clearHeaders();
|
||||||
|
String line = readIntoCurrentLine(buffer);
|
||||||
|
String lastHeader = null;
|
||||||
|
while (!line.equals("")) {
|
||||||
|
if (line.startsWith(" ") || line.startsWith("\t")) {
|
||||||
|
List<String> current = message.getHeaders(lastHeader);
|
||||||
|
int lastPos = current.size() - 1;
|
||||||
|
String newString = current.get(lastPos) + line.trim();
|
||||||
|
current.remove(lastPos);
|
||||||
|
current.add(newString);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
String[] header = splitHeader(line);
|
||||||
|
message.addHeader(header[0], header[1]);
|
||||||
|
lastHeader = header[0];
|
||||||
|
}
|
||||||
|
line = readIntoCurrentLine(buffer);
|
||||||
|
}
|
||||||
|
ResponseState nextState;
|
||||||
|
if (message.getContentLength() > 0) {
|
||||||
|
nextState = ResponseState.READ_FIXED_LENGTH_CONTENT;
|
||||||
|
}
|
||||||
|
else if (message.isChunked()) {
|
||||||
|
nextState = ResponseState.READ_CHUNK_SIZE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nextState = ResponseState.READ_CONTENT;
|
||||||
|
}
|
||||||
|
checkpoint(nextState);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void readInitial(ChannelBuffer buffer) throws Exception;
|
||||||
|
|
||||||
|
private int getChunkSize(String hex) {
|
||||||
|
return Integer.valueOf(hex, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String readIntoCurrentLine(ChannelBuffer channel) {
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
while (true) {
|
||||||
|
byte nextByte = channel.readByte();
|
||||||
|
if (nextByte == HttpCodecUtil.CR) {
|
||||||
|
channel.readByte();
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
else if (nextByte == HttpCodecUtil.LF) {
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sb.append((char) nextByte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String[] splitInitial(String sb) {
|
||||||
|
String[] split = sb.split(" ");
|
||||||
|
if (split.length != 3) {
|
||||||
|
throw new IllegalArgumentException(sb + "does not contain all 3 parts");
|
||||||
|
}
|
||||||
|
return split;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] splitHeader(String sb) {
|
||||||
|
String[] split = sb.split(":", 2);
|
||||||
|
if (split.length != 2) {
|
||||||
|
throw new IllegalArgumentException(sb + "does not contain all 2 parts");
|
||||||
|
}
|
||||||
|
for (int i = 0; i < split.length; i++) {
|
||||||
|
split[i] = split[i].trim();
|
||||||
|
}
|
||||||
|
return split;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
import static org.jboss.netty.channel.Channels.*;
|
||||||
|
import static org.jboss.netty.handler.codec.http.HttpCodecUtil.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jboss.netty.buffer.ChannelBuffer;
|
||||||
|
import org.jboss.netty.buffer.ChannelBuffers;
|
||||||
|
import org.jboss.netty.channel.ChannelHandlerContext;
|
||||||
|
import org.jboss.netty.channel.ChannelPipelineCoverage;
|
||||||
|
import org.jboss.netty.channel.MessageEvent;
|
||||||
|
import org.jboss.netty.channel.SimpleChannelHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* encodes an http message
|
||||||
|
*
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
* @author Trustin Lee (tlee@redhat.com)
|
||||||
|
*/
|
||||||
|
@ChannelPipelineCoverage("one")
|
||||||
|
public abstract class HttpMessageEncoder extends SimpleChannelHandler {
|
||||||
|
@Override
|
||||||
|
public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
|
||||||
|
if (!(e.getMessage() instanceof HttpMessage)) {
|
||||||
|
ctx.sendDownstream(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
HttpMessage request = (HttpMessage) e.getMessage();
|
||||||
|
ChannelBuffer buf = ChannelBuffers.dynamicBuffer();
|
||||||
|
encodeInitialLine(buf, request);
|
||||||
|
encodeHeaders(buf, request);
|
||||||
|
buf.writeBytes(CRLF);
|
||||||
|
if (request.getContent() != null) {
|
||||||
|
buf.writeBytes(request.getContent());
|
||||||
|
}
|
||||||
|
write(ctx, e.getChannel(), e.getFuture(), buf, e.getRemoteAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* writes the headers
|
||||||
|
* Header1: value1
|
||||||
|
* Header2: value2
|
||||||
|
*
|
||||||
|
* @param buf
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
public void encodeHeaders(ChannelBuffer buf, HttpMessage message) {
|
||||||
|
Set<String> headers = message.getHeaderNames();
|
||||||
|
for (String header : headers) {
|
||||||
|
List<String> values = message.getHeaders(header);
|
||||||
|
for (String value : values) {
|
||||||
|
|
||||||
|
buf.writeBytes(header.getBytes());
|
||||||
|
buf.writeByte(COLON);
|
||||||
|
buf.writeByte(SP);
|
||||||
|
buf.writeBytes(value.getBytes());
|
||||||
|
buf.writeBytes(CRLF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void encodeInitialLine(ChannelBuffer buf, HttpMessage message) throws Exception;
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This defines the methods available via a HTTP Request.
|
||||||
|
*
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
*/
|
||||||
|
public enum HttpMethod {
|
||||||
|
/**
|
||||||
|
* The OPTIONS method represents a request for information about the communication options available on the request/response
|
||||||
|
* chain identified by the Request-URI. This method allows the client to determine the options and/or requirements
|
||||||
|
* associated with a resource, or the capabilities of a server, without implying a resource action or initiating a
|
||||||
|
* resource retrieval.
|
||||||
|
*/
|
||||||
|
OPTIONS("OPTIONS"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI.
|
||||||
|
* If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the entity
|
||||||
|
* in the response and not the source text of the process, unless that text happens to be the output of the process.
|
||||||
|
*/
|
||||||
|
GET("GET"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response.
|
||||||
|
*/
|
||||||
|
HEAD("HEAD"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The POST method is used to request that the origin server accept the entity enclosed in the request as a new
|
||||||
|
* subordinate of the resource identified by the Request-URI in the Request-Line.
|
||||||
|
*/
|
||||||
|
POST("POST"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PUT method requests that the enclosed entity be stored under the supplied Request-URI.
|
||||||
|
*/
|
||||||
|
PUT("PUT"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The DELETE method requests that the origin server delete the resource identified by the Request-URI.
|
||||||
|
*/
|
||||||
|
DELETE("DELETE"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The TRACE method is used to invoke a remote, application-layer loop- back of the request message.
|
||||||
|
*/
|
||||||
|
TRACE("TRACE"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This specification reserves the method name CONNECT for use with a proxy that can dynamically switch to being a tunnel
|
||||||
|
*/
|
||||||
|
CONNECT("CONNECT"),;
|
||||||
|
|
||||||
|
private String method;
|
||||||
|
|
||||||
|
|
||||||
|
private HttpMethod(String method) {
|
||||||
|
this.method = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMethod() {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An http request.
|
||||||
|
*
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
*/
|
||||||
|
public interface HttpRequest extends HttpMessage {
|
||||||
|
|
||||||
|
boolean isKeepAlive();
|
||||||
|
|
||||||
|
HttpMethod getMethod();
|
||||||
|
|
||||||
|
URI getURI();
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.jboss.netty.buffer.ChannelBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* decodes an http request.
|
||||||
|
*
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
* @author Trustin Lee (tlee@redhat.com)
|
||||||
|
*/
|
||||||
|
public class HttpRequestDecoder extends HttpMessageDecoder {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void readInitial(ChannelBuffer buffer) throws Exception{
|
||||||
|
String line = readIntoCurrentLine(buffer);
|
||||||
|
checkpoint(ResponseState.READ_HEADER);
|
||||||
|
String[] split = splitInitial(line);
|
||||||
|
message = new DefaultHttpRequest(HttpVersion.getProtocol(split[2]), HttpMethod.valueOf(split[0]), new URI(split[1]));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
import static org.jboss.netty.handler.codec.http.HttpCodecUtil.*;
|
||||||
|
|
||||||
|
import org.jboss.netty.buffer.ChannelBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* encodes an http request
|
||||||
|
*
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
* @author Trustin Lee (tlee@redhat.com)
|
||||||
|
*/
|
||||||
|
public class HttpRequestEncoder extends HttpMessageEncoder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* writes the initial line i.e. 'GET /path/to/file/index.html HTTP/1.0'
|
||||||
|
*
|
||||||
|
* @param buf
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void encodeInitialLine(ChannelBuffer buf, HttpMessage message) throws Exception {
|
||||||
|
HttpRequest request = (HttpRequest) message;
|
||||||
|
buf.writeBytes(request.getMethod().getMethod().getBytes());
|
||||||
|
buf.writeByte(SP);
|
||||||
|
buf.writeBytes(request.getURI().toASCIIString().getBytes());
|
||||||
|
buf.writeByte(SP);
|
||||||
|
buf.writeBytes(request.getProtocolVersion().value().getBytes());
|
||||||
|
buf.writeBytes(CRLF);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* an http response.
|
||||||
|
*
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
* @author Trustin Lee (tlee@redhat.com)
|
||||||
|
*/
|
||||||
|
public interface HttpResponse extends HttpMessage {
|
||||||
|
HttpResponseStatus getStatus();
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
import org.jboss.netty.buffer.ChannelBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* an http response decoder
|
||||||
|
*
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
* @author Trustin Lee (tlee@redhat.com)
|
||||||
|
*/
|
||||||
|
public class HttpResponseDecoder extends HttpMessageDecoder {
|
||||||
|
@Override
|
||||||
|
protected void readInitial(ChannelBuffer buffer) {
|
||||||
|
String line = readIntoCurrentLine(buffer);
|
||||||
|
checkpoint(ResponseState.READ_HEADER);
|
||||||
|
String[] split = splitInitial(line);
|
||||||
|
message = new DefaultHttpResponse(HttpVersion.getProtocol(split[0]), new HttpResponseStatus(Integer.valueOf(split[1]), split[2]));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
import static org.jboss.netty.handler.codec.http.HttpCodecUtil.*;
|
||||||
|
|
||||||
|
import org.jboss.netty.buffer.ChannelBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* encodes an http response
|
||||||
|
*
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
* @author Trustin Lee (tlee@redhat.com)
|
||||||
|
*/
|
||||||
|
public class HttpResponseEncoder extends HttpMessageEncoder {
|
||||||
|
@Override
|
||||||
|
protected void encodeInitialLine(ChannelBuffer buf, HttpMessage message) {
|
||||||
|
HttpResponse response = (HttpResponse) message;
|
||||||
|
buf.writeBytes(response.getProtocolVersion().value().getBytes());
|
||||||
|
buf.writeByte(SP);
|
||||||
|
buf.writeBytes(String.valueOf(response.getStatus().getCode()).getBytes());
|
||||||
|
buf.writeByte(SP);
|
||||||
|
buf.writeBytes(String.valueOf(response.getStatus().getReasonPhrase()).getBytes());
|
||||||
|
buf.writeBytes(CRLF);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The response codes and descriptions to return in the response. see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
||||||
|
*
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
* @author Trustin Lee (tlee@redhat.com)
|
||||||
|
*/
|
||||||
|
public class HttpResponseStatus {
|
||||||
|
|
||||||
|
public static final HttpResponseStatus CONTINUE = new HttpResponseStatus(100, "Continue");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus SWITCHING_PROTOCOLS = new HttpResponseStatus(101, "Switching Protocols");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus OK = new HttpResponseStatus(200, "OK");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus CREATED = new HttpResponseStatus(201, "Created");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus ACCEPTED = new HttpResponseStatus(202, "Accepted");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus NON_AUTHORITATIVE_INFORMATION = new HttpResponseStatus(203, "Non-Authoritative Information");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus NO_CONTENT = new HttpResponseStatus(204, "No Content");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus RESET_CONTENT = new HttpResponseStatus(205, "Reset Content");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus PARTIAL_CONTENT = new HttpResponseStatus(206, "Partial Content");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus MULTIPLE_CHOICES = new HttpResponseStatus(300, "Multiple Choices");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus MOVED_PERMANENTLY = new HttpResponseStatus(301, "Moved Permanently");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus FOUND = new HttpResponseStatus(302, "Found");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus SEE_OTHER = new HttpResponseStatus(303, "See Other");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus NOT_MODIFIED = new HttpResponseStatus(304, "Not Modified");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus USE_PROXY = new HttpResponseStatus(305, "Use Proxy");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus TEMPORARY_REDIRECT = new HttpResponseStatus(307, "Temporary Redirect");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus BAD_REQUEST = new HttpResponseStatus(400, "Bad Request");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus UNUATHORIZED = new HttpResponseStatus(401, "Unauthorized");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus PAYMENT_REQUIRED = new HttpResponseStatus(402, "Payment Required");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus FORBIDDEN = new HttpResponseStatus(403, "Forbidden");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus NOT_FOUND = new HttpResponseStatus(404, "Not Found");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus METHOD_NOT_ALLOWED = new HttpResponseStatus(405, "Method Not Allowed");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus NOT_ACCEPTABLE = new HttpResponseStatus(406, "Not Acceptable");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus PROXY_AUTHENTICATION_REQUIRED = new HttpResponseStatus(407, "Proxy Authentication Required");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus REQUEST_TIMEOUT = new HttpResponseStatus(408, "Request Timeout");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus CONFLICT = new HttpResponseStatus(409, "Conflict");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus GONE = new HttpResponseStatus(410, "Gone");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus LENGTH_REQUIRED = new HttpResponseStatus(411, "Length Required");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus PRECONDITION_FAILED = new HttpResponseStatus(412, "Precondition Failed");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus REQUEST_ENTITY_TOO_LARGE = new HttpResponseStatus(413, "Request Entity Too Large");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus REQUEST_URI_TOO_LONG = new HttpResponseStatus(414, "Request-URI Too Long");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus UNSUPPORTED_MEDIA_TYPE = new HttpResponseStatus(415, "Unsupported Media Type");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus REQUESTED_RANGE_NOT_SATISFIABLE = new HttpResponseStatus(416, "Requested Range Not Satisfiable");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus EXPECTATION_FAILED = new HttpResponseStatus(417, "Expectation Failed");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus INTERNAL_SERVER_ERROR = new HttpResponseStatus(500, "Internal Server Error");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus NOT_IMPLEMENTED = new HttpResponseStatus(501, "Not Implemented");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus BAD_GATEWAY = new HttpResponseStatus(502, "Bad Gateway");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus SERVICE_UNAVAILABLE = new HttpResponseStatus(503, "Service Unavailable");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus GATEWAY_TIMEOUT = new HttpResponseStatus(504, "Gateway Timeout");
|
||||||
|
|
||||||
|
public static final HttpResponseStatus HTTP_VERSION_NOT_SUPPORTED = new HttpResponseStatus(505, "HTTP Version Not Supported");
|
||||||
|
|
||||||
|
|
||||||
|
private final int code;
|
||||||
|
|
||||||
|
private final String reasonPhrase;
|
||||||
|
|
||||||
|
public HttpResponseStatus(int code, String reasonPhrase) {
|
||||||
|
this.code = code;
|
||||||
|
this.reasonPhrase = reasonPhrase;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReasonPhrase() {
|
||||||
|
return reasonPhrase;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The protocols we support;
|
||||||
|
*
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
* @author Trustin Lee (tlee@redhat.com)
|
||||||
|
*/
|
||||||
|
public enum HttpVersion {
|
||||||
|
HTTP_1_0("HTTP/1.0"),
|
||||||
|
|
||||||
|
HTTP_1_1("HTTP/1.1"),
|
||||||
|
|
||||||
|
UNKNOWN("UNKNOWN"),;
|
||||||
|
|
||||||
|
private String version;
|
||||||
|
|
||||||
|
private HttpVersion(String value) {
|
||||||
|
version = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String value() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HttpVersion getProtocol(String value) {
|
||||||
|
if (value == null) {
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
else if (value.equals(HTTP_1_0.value())) {
|
||||||
|
return HTTP_1_0;
|
||||||
|
}
|
||||||
|
else if (value.equals(HTTP_1_1.value())) {
|
||||||
|
return HTTP_1_1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
*/
|
||||||
|
public class QueryStringDecoder {
|
||||||
|
|
||||||
|
private final String uri;
|
||||||
|
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
private final Map<String, List<String>> params = new HashMap<String, List<String>>();
|
||||||
|
|
||||||
|
public QueryStringDecoder(String uri) {
|
||||||
|
this.uri = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueryStringDecoder(URI uri){
|
||||||
|
this.uri = uri.toASCIIString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPath() {
|
||||||
|
//decode lazily
|
||||||
|
if(path == null) {
|
||||||
|
if(uri.contains("?")) {
|
||||||
|
decode();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
path = uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, List<String>> getParameters() {
|
||||||
|
if(path == null){
|
||||||
|
if(uri.contains("?")) {
|
||||||
|
decode();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
path = uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void decode() {
|
||||||
|
String[] split = uri.split("\\?", 2);
|
||||||
|
path = split[0];
|
||||||
|
decodeParams(split[1]);
|
||||||
|
}
|
||||||
|
//todo - just replacing spaces at the minute, should we check for all characters or leave this to the user?
|
||||||
|
private void decodeParams(String s) {
|
||||||
|
String[] params = s.split("&");
|
||||||
|
for (String param : params) {
|
||||||
|
String[] split = param.split("=");
|
||||||
|
String key = removeSpaceDelimeters(split[0]);
|
||||||
|
List<String> values = this.params.get(key);
|
||||||
|
if(values == null) {
|
||||||
|
values = new ArrayList<String>();
|
||||||
|
this.params.put(key,values);
|
||||||
|
}
|
||||||
|
values.add(removeSpaceDelimeters(split[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String removeSpaceDelimeters(String s) {
|
||||||
|
return s.replaceAll("%20", " ");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source
|
||||||
|
* Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
|
||||||
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
||||||
|
* full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.jboss.netty.handler.codec.http;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author The Netty Project (netty-dev@lists.jboss.org)
|
||||||
|
* @author Andy Taylor (andy.taylor@jboss.org)
|
||||||
|
*/
|
||||||
|
public class QueryStringEncoder {
|
||||||
|
|
||||||
|
final String url;
|
||||||
|
|
||||||
|
final List<Param> params = new ArrayList<Param>();
|
||||||
|
|
||||||
|
public QueryStringEncoder(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addParam(String name, String value) {
|
||||||
|
if(name == null) {
|
||||||
|
throw new NullPointerException("name is null");
|
||||||
|
}
|
||||||
|
if(value == null) {
|
||||||
|
throw new NullPointerException("value is null");
|
||||||
|
}
|
||||||
|
params.add(new Param(name, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public URI toUri() throws URISyntaxException {
|
||||||
|
if (params.size() == 0) {
|
||||||
|
return new URI(url);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
StringBuffer sb = new StringBuffer(url).append("?");
|
||||||
|
for (int i = 0; i < params.size(); i++) {
|
||||||
|
Param param = params.get(i);
|
||||||
|
sb.append(replaceSpaces(param.name)).append("=").append(replaceSpaces(param.value));
|
||||||
|
if(i != params.size() - 1) {
|
||||||
|
sb.append("&");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new URI(sb.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String replaceSpaces(String s) {
|
||||||
|
return s.replaceAll(" ", "%20");
|
||||||
|
}
|
||||||
|
|
||||||
|
class Param {
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
final String value;
|
||||||
|
|
||||||
|
public Param(String name, String value) {
|
||||||
|
this.value = value;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user