From fea082e68914a686b6f33322b66af3bfb16a1100 Mon Sep 17 00:00:00 2001 From: Andy Taylor Date: Tue, 17 Feb 2009 17:13:13 +0000 Subject: [PATCH] fixed cookie support --- .../jboss/netty/example/http/HttpClient.java | 6 +- .../example/http/HttpRequestHandler.java | 15 +++- .../codec/http/DefaultHttpMessage.java | 31 +------- .../handler/codec/http/HttpCookieDecoder.java | 46 ++++++++++++ .../handler/codec/http/HttpCookieEncoder.java | 70 +++++++++++++++++++ .../netty/handler/codec/http/HttpHeaders.java | 2 + .../netty/handler/codec/http/HttpMessage.java | 8 --- .../codec/http/HttpMessageDecoder.java | 1 - .../codec/http/HttpMessageEncoder.java | 19 ----- .../codec/http/HttpRequestDecoder.java | 5 -- .../codec/http/HttpRequestEncoder.java | 6 -- .../codec/http/HttpResponseDecoder.java | 5 -- .../codec/http/HttpResponseEncoder.java | 5 -- .../netty/util/CaseIgnoringComparator.java | 41 +++++++++++ 14 files changed, 179 insertions(+), 81 deletions(-) create mode 100644 src/main/java/org/jboss/netty/handler/codec/http/HttpCookieDecoder.java create mode 100644 src/main/java/org/jboss/netty/handler/codec/http/HttpCookieEncoder.java create mode 100644 src/main/java/org/jboss/netty/util/CaseIgnoringComparator.java diff --git a/src/main/java/org/jboss/netty/example/http/HttpClient.java b/src/main/java/org/jboss/netty/example/http/HttpClient.java index a5f3d20a0e..3c73ff3ea8 100644 --- a/src/main/java/org/jboss/netty/example/http/HttpClient.java +++ b/src/main/java/org/jboss/netty/example/http/HttpClient.java @@ -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. diff --git a/src/main/java/org/jboss/netty/example/http/HttpRequestHandler.java b/src/main/java/org/jboss/netty/example/http/HttpRequestHandler.java index daa2942c12..899137b3a0 100644 --- a/src/main/java/org/jboss/netty/example/http/HttpRequestHandler.java +++ b/src/main/java/org/jboss/netty/example/http/HttpRequestHandler.java @@ -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 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); diff --git a/src/main/java/org/jboss/netty/handler/codec/http/DefaultHttpMessage.java b/src/main/java/org/jboss/netty/handler/codec/http/DefaultHttpMessage.java index b4508ba5e6..b8bbf449d6 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/DefaultHttpMessage.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/DefaultHttpMessage.java @@ -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> headers = new TreeMap>(caseIgnoringComparator); - private final Map cookies = new TreeMap(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 getCookies() { - return cookies.values(); - } - public Collection getCookieNames() { - return cookies.keySet(); - } - - private static final class CaseIgnoringComparator - implements Comparator, Serializable { - - private static final long serialVersionUID = 4582133183775373862L; - - CaseIgnoringComparator() { - super(); - } - - public int compare(String o1, String o2) { - return o1.compareToIgnoreCase(o2); - } - } } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpCookieDecoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpCookieDecoder.java new file mode 100644 index 0000000000..9732291f1e --- /dev/null +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpCookieDecoder.java @@ -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 Andy Taylor + */ +public class HttpCookieDecoder { + private final static String semicolon = ";"; + + private final static String equals = "="; + + public Set decode(String header) { + Set cookies = new HashSet(); + 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; + } +} diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpCookieEncoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpCookieEncoder.java new file mode 100644 index 0000000000..ee6b91010f --- /dev/null +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpCookieEncoder.java @@ -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 Andy Taylor + */ +public class HttpCookieEncoder { + private final static String semicolon = ";"; + + private final static String equals = "="; + + private final static Comparator caseIgnoringComparator = new CaseIgnoringComparator(); + + private final Map cookies = new TreeMap(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 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(); + } +} diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpHeaders.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpHeaders.java index 9f029b90ef..74582caf9d 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpHeaders.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpHeaders.java @@ -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"; diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpMessage.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpMessage.java index e77b8a8d33..2a7e956031 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpMessage.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpMessage.java @@ -65,13 +65,5 @@ public interface HttpMessage { boolean isChunked(); void clearHeaders(); - - void addCookie(HttpCookie cookie); - - HttpCookie getCookie(String name); - - Collection getCookies(); - - Collection getCookieNames(); } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java index d31fa4a9af..ef36611dce 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java @@ -258,7 +258,6 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder 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; } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestDecoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestDecoder.java index 0b492b96b3..08c94359e8 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestDecoder.java @@ -54,9 +54,4 @@ public class HttpRequestDecoder extends HttpMessageDecoder { protected boolean isDecodingRequest() { return true; } - - @Override - protected String getCookieHeaderName() { - return "Cookie"; - } } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestEncoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestEncoder.java index ab2ddb39bb..cb3984201e 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestEncoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestEncoder.java @@ -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; - } } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseDecoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseDecoder.java index 8f97f9476a..d5b55bb85d 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseDecoder.java @@ -53,9 +53,4 @@ public class HttpResponseDecoder extends HttpMessageDecoder { protected boolean isDecodingRequest() { return false; } - - @Override - protected String getCookieHeaderName() { - return "Set-Cookie"; - } } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseEncoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseEncoder.java index a73865eaed..df3681863b 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseEncoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseEncoder.java @@ -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; - } } diff --git a/src/main/java/org/jboss/netty/util/CaseIgnoringComparator.java b/src/main/java/org/jboss/netty/util/CaseIgnoringComparator.java new file mode 100644 index 0000000000..e9e1e9d299 --- /dev/null +++ b/src/main/java/org/jboss/netty/util/CaseIgnoringComparator.java @@ -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 Andy Taylor + */ +public class CaseIgnoringComparator implements Comparator, Serializable { + + private static final long serialVersionUID = 4582133183775373862L; + + public CaseIgnoringComparator() { + super(); + } + + public int compare(String o1, String o2) { + return o1.compareToIgnoreCase(o2); + } +} \ No newline at end of file