fixed cookie support

This commit is contained in:
Andy Taylor 2009-02-17 17:13:13 +00:00
parent e424c5f87d
commit fea082e689
14 changed files with 179 additions and 81 deletions

View File

@ -35,6 +35,7 @@ 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.HttpCookieEncoder;
/**
* @author The Netty Project (netty-dev@lists.jboss.org)
@ -90,7 +91,10 @@ public class HttpClient {
HttpRequest request = new DefaultHttpRequest(
HttpVersion.HTTP_1_0, HttpMethod.GET, uri.toASCIIString());
request.addHeader(HttpHeaders.Names.HOST, host);
HttpCookieEncoder httpCookieEncoder = new HttpCookieEncoder();
httpCookieEncoder.addCookie("my-cookie", "foo");
httpCookieEncoder.addCookie("another-cookie", "bar");
request.addHeader(HttpHeaders.Names.COOKIE, httpCookieEncoder.encode());
channel.write(request);
// Wait for the server to close the connection.

View File

@ -23,6 +23,7 @@ package org.jboss.netty.example.http;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import org.jboss.netty.buffer.ChannelBuffer;
@ -41,6 +42,9 @@ 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;
import org.jboss.netty.handler.codec.http.HttpCookieDecoder;
import org.jboss.netty.handler.codec.http.HttpCookie;
import org.jboss.netty.handler.codec.http.HttpCookieEncoder;
/**
* @author The Netty Project (netty-dev@lists.jboss.org)
@ -127,7 +131,16 @@ public class HttpRequestHandler extends SimpleChannelHandler {
response.setContent(buf);
response.setHeader(HttpHeaders.Names.CONTENT_TYPE, "text/plain; charset=UTF-8");
response.setHeader(HttpHeaders.Names.CONTENT_LENGTH, String.valueOf(buf.readableBytes()));
HttpCookieDecoder cookieDecoder = new HttpCookieDecoder();
Set<HttpCookie> cookieSet = cookieDecoder.decode(request.getHeader(HttpHeaders.Names.COOKIE));
if(cookieSet != null) {
//lets reset the cookies
HttpCookieEncoder cookieEncoder = new HttpCookieEncoder();
for (HttpCookie cookie : cookieSet) {
cookieEncoder.addCookie(cookie);
}
response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode());
}
// Write the response.
ChannelFuture future = e.getChannel().write(response);

View File

@ -31,6 +31,7 @@ import java.util.TreeMap;
import java.util.Collection;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.util.CaseIgnoringComparator;
/**
* a default Http Message which holds the headers and body.
@ -45,7 +46,6 @@ public class DefaultHttpMessage implements HttpMessage {
private final HttpVersion version;
private final Map<String, List<String>> headers = new TreeMap<String, List<String>>(caseIgnoringComparator);
private final Map<String, HttpCookie> cookies = new TreeMap<String, HttpCookie>(caseIgnoringComparator);
private ChannelBuffer content;
protected DefaultHttpMessage(final HttpVersion version) {
@ -141,33 +141,4 @@ public class DefaultHttpMessage implements HttpMessage {
public ChannelBuffer getContent() {
return content;
}
public void addCookie(HttpCookie cookie) {
cookies.put(cookie.getName(), cookie);
}
public HttpCookie getCookie(String name) {
return cookies.get(name);
}
public Collection<HttpCookie> getCookies() {
return cookies.values();
}
public Collection<String> getCookieNames() {
return cookies.keySet();
}
private static final class CaseIgnoringComparator
implements Comparator<String>, Serializable {
private static final long serialVersionUID = 4582133183775373862L;
CaseIgnoringComparator() {
super();
}
public int compare(String o1, String o2) {
return o1.compareToIgnoreCase(o2);
}
}
}

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 java.util.Set;
import java.util.HashSet;
/**
* @author <a href="mailto:andy.taylor@jboss.org">Andy Taylor</a>
*/
public class HttpCookieDecoder {
private final static String semicolon = ";";
private final static String equals = "=";
public Set<HttpCookie> decode(String header) {
Set<HttpCookie> cookies = new HashSet<HttpCookie>();
String[] split = header.split(semicolon);
for (String s : split) {
String[] cookie = s.split(equals);
if(cookie != null && cookie.length == 2) {
cookies.add(new HttpCookie(cookie[0].trim(), cookie[1].trim()));
}
}
return cookies;
}
}

View File

@ -0,0 +1,70 @@
/*
* 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.util.CaseIgnoringComparator;
import static org.jboss.netty.handler.codec.http.HttpCodecUtil.COLON;
import static org.jboss.netty.handler.codec.http.HttpCodecUtil.SP;
import static org.jboss.netty.handler.codec.http.HttpCodecUtil.EQUALS;
import static org.jboss.netty.handler.codec.http.HttpCodecUtil.SEMICOLON;
import static org.jboss.netty.handler.codec.http.HttpCodecUtil.CRLF;
import java.util.Map;
import java.util.TreeMap;
import java.util.Comparator;
import java.util.Collection;
/**
* @author <a href="mailto:andy.taylor@jboss.org">Andy Taylor</a>
*/
public class HttpCookieEncoder {
private final static String semicolon = ";";
private final static String equals = "=";
private final static Comparator<String> caseIgnoringComparator = new CaseIgnoringComparator();
private final Map<String, HttpCookie> cookies = new TreeMap<String, HttpCookie>(caseIgnoringComparator);
public void addCookie(String name, String val) {
cookies.put(name, new HttpCookie(name, val));
}
public void addCookie(HttpCookie cookie) {
cookies.put(cookie.getName(), cookie);
}
public String encode() {
StringBuffer sb = new StringBuffer();
Collection<String> cookieNames = cookies.keySet();
if(cookieNames.isEmpty()) {
return null;
}
for (String cookieName : cookieNames) {
sb.append(cookieName);
sb.append(equals);
sb.append(cookies.get(cookieName).getValue());
sb.append(semicolon);
}
return sb.toString();
}
}

View File

@ -46,6 +46,7 @@ public final class HttpHeaders {
public static final String CONTENT_MD5 = "Content-MD5";
public static final String CONTENT_RANGE = "Content-Range";
public static final String CONTENT_TYPE= "Content-Type";
public static final String COOKIE = "Cookie";
public static final String DATE = "Date";
public static final String ETAG = "ETag";
public static final String EXPECT = "Expect";
@ -67,6 +68,7 @@ public final class HttpHeaders {
public static final String REFERER = "Referer";
public static final String RETRY_AFTER = "Retry-After";
public static final String SERVER = "Server";
public static final String SET_COOKIE = "Set-Cookie";
public static final String TE = "TE";
public static final String TRAILER = "Trailer";
public static final String TRANSFER_ENCODING = "Transfer-Encoding";

View File

@ -65,13 +65,5 @@ public interface HttpMessage {
boolean isChunked();
void clearHeaders();
void addCookie(HttpCookie cookie);
HttpCookie getCookie(String name);
Collection<HttpCookie> getCookies();
Collection<String> getCookieNames();
}

View File

@ -258,7 +258,6 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder<HttpMessageDec
}
protected abstract boolean isDecodingRequest();
protected abstract String getCookieHeaderName();
protected abstract void readInitial(ChannelBuffer buffer) throws Exception;
private int getChunkSize(String hex) {

View File

@ -56,7 +56,6 @@ public abstract class HttpMessageEncoder extends OneToOneEncoder {
channel.getConfig().getBufferFactory());
encodeInitialLine(header, request);
encodeHeaders(header, request);
encodeCookies(header, request);
header.writeBytes(CRLF);
ChannelBuffer content = request.getContent();
@ -110,23 +109,5 @@ public abstract class HttpMessageEncoder extends OneToOneEncoder {
}
}
public void encodeCookies(ChannelBuffer buf, HttpMessage message) {
Collection<String> cookieNames = message.getCookieNames();
if(cookieNames.isEmpty()) {
return;
}
buf.writeBytes(getCookieHeaderName());
buf.writeByte(COLON);
buf.writeByte(SP);
for (String cookieName : cookieNames) {
buf.writeBytes(cookieName.getBytes());
buf.writeByte(EQUALS);
buf.writeBytes(message.getCookie(cookieName).getValue().getBytes());
buf.writeByte(SEMICOLON);
}
buf.writeBytes(CRLF);
}
protected abstract byte[] getCookieHeaderName();
protected abstract void encodeInitialLine(ChannelBuffer buf, HttpMessage message) throws Exception;
}

View File

@ -54,9 +54,4 @@ public class HttpRequestDecoder extends HttpMessageDecoder {
protected boolean isDecodingRequest() {
return true;
}
@Override
protected String getCookieHeaderName() {
return "Cookie";
}
}

View File

@ -34,7 +34,6 @@ import org.jboss.netty.buffer.ChannelBuffer;
* @version $Rev$, $Date$
*/
public class HttpRequestEncoder extends HttpMessageEncoder {
private static final byte[] COOKIE_HEADER = "Cookie".getBytes();
/**
* writes the initial line i.e. 'GET /path/to/file/index.html HTTP/1.0'
*/
@ -48,9 +47,4 @@ public class HttpRequestEncoder extends HttpMessageEncoder {
buf.writeBytes(request.getProtocolVersion().toString().getBytes());
buf.writeBytes(CRLF);
}
@Override
protected byte[] getCookieHeaderName() {
return COOKIE_HEADER;
}
}

View File

@ -53,9 +53,4 @@ public class HttpResponseDecoder extends HttpMessageDecoder {
protected boolean isDecodingRequest() {
return false;
}
@Override
protected String getCookieHeaderName() {
return "Set-Cookie";
}
}

View File

@ -34,7 +34,6 @@ import org.jboss.netty.buffer.ChannelBuffer;
* @version $Rev$, $Date$
*/
public class HttpResponseEncoder extends HttpMessageEncoder {
private static final byte[] COOKIE_HEADER = "Set Cookie: ".getBytes();
@Override
protected void encodeInitialLine(ChannelBuffer buf, HttpMessage message) {
@ -47,8 +46,4 @@ public class HttpResponseEncoder extends HttpMessageEncoder {
buf.writeBytes(CRLF);
}
@Override
protected byte[] getCookieHeaderName() {
return COOKIE_HEADER;
}
}

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.util;
import java.io.Serializable;
import java.util.Comparator;
/**
* @author <a href="mailto:andy.taylor@jboss.org">Andy Taylor</a>
*/
public class CaseIgnoringComparator implements Comparator<String>, Serializable {
private static final long serialVersionUID = 4582133183775373862L;
public CaseIgnoringComparator() {
super();
}
public int compare(String o1, String o2) {
return o1.compareToIgnoreCase(o2);
}
}