Merged the HTTP branch into the trunk

This commit is contained in:
Trustin Lee 2008-11-19 07:22:15 +00:00
parent e29ba2eed5
commit 4ac032c657
27 changed files with 1853 additions and 0 deletions

View File

@ -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
------------------------------------------------------------------------------- -------------------------------------------------------------------------------

View 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();
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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()));
}
}

View 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));
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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";
}
}

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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]));
}
}

View File

@ -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);
}
}

View File

@ -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();
}

View File

@ -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]));
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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", " ");
}
}

View File

@ -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;
}
}
}