1 /*
2 * Copyright 2012 The Netty Project
3 *
4 * The Netty Project licenses this file to you under the Apache License,
5 * version 2.0 (the "License"); you may not use this file except in compliance
6 * with the License. You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
14 * under the License.
15 */
16 package org.jboss.netty.handler.codec.http;
17
18 import org.jboss.netty.handler.codec.http.cookie.ClientCookieEncoder;
19 import org.jboss.netty.handler.codec.http.cookie.ServerCookieEncoder;
20
21 import java.util.Set;
22 import java.util.TreeSet;
23
24 /**
25 * Encodes {@link Cookie}s into an HTTP header value. This encoder can encode
26 * the HTTP cookie version 0, 1, and 2.
27 * <p>
28 * This encoder is stateful. It maintains an internal data structure that
29 * holds the {@link Cookie}s added by the {@link #addCookie(String, String)}
30 * method. Once {@link #encode()} is called, all added {@link Cookie}s are
31 * encoded into an HTTP header value and all {@link Cookie}s in the internal
32 * data structure are removed so that the encoder can start over.
33 * <pre>
34 * // Client-side example
35 * {@link HttpRequest} req = ...;
36 * {@link CookieEncoder} encoder = new {@link CookieEncoder}(false);
37 * encoder.addCookie("JSESSIONID", "1234");
38 * res.setHeader("Cookie", encoder.encode());
39 *
40 * // Server-side example
41 * {@link HttpResponse} res = ...;
42 * {@link CookieEncoder} encoder = new {@link CookieEncoder}(true);
43 * encoder.addCookie("JSESSIONID", "1234");
44 * res.setHeader("Set-Cookie", encoder.encode());
45 * </pre>
46 *
47 * @see CookieDecoder
48 *
49 * @apiviz.stereotype utility
50 * @apiviz.has org.jboss.netty.handler.codec.http.Cookie oneway - - encodes
51 */
52 public class CookieEncoder {
53
54 private final Set<Cookie> cookies = new TreeSet<Cookie>();
55 private final boolean server;
56 private final boolean strict;
57
58 /**
59 * Creates a new encoder.
60 *
61 * @param server {@code true} if and only if this encoder is supposed to
62 * encode server-side cookies. {@code false} if and only if
63 * this encoder is supposed to encode client-side cookies.
64 */
65 public CookieEncoder(boolean server) {
66 this(server, false);
67 }
68
69 /**
70 * Creates a new encoder.
71 *
72 * @param server {@code true} if and only if this encoder is supposed to
73 * encode server-side cookies. {@code false} if and only if
74 * this encoder is supposed to encode client-side cookies.
75 * @param strict {@code true} if and only if this encoder is supposed to
76 * validate characters according to RFC6265.
77 */
78 public CookieEncoder(boolean server, boolean strict) {
79 this.server = server;
80 this.strict = strict;
81 }
82
83 /**
84 * Adds a new {@link Cookie} created with the specified name and value to
85 * this encoder.
86 */
87 public void addCookie(String name, String value) {
88 cookies.add(new DefaultCookie(name, value));
89 }
90
91 /**
92 * Adds the specified {@link Cookie} to this encoder.
93 */
94 public void addCookie(Cookie cookie) {
95 cookies.add(cookie);
96 }
97
98 /**
99 * Encodes the {@link Cookie}s which were added by {@link #addCookie(Cookie)}
100 * so far into an HTTP header value. If no {@link Cookie}s were added,
101 * an empty string is returned.
102 *
103 * <strong>Be aware that calling this method will clear the content of the {@link CookieEncoder}</strong>
104 */
105 public String encode() {
106 String answer;
107 if (server) {
108 answer = encodeServerSide();
109 } else {
110 answer = encodeClientSide();
111 }
112 cookies.clear();
113 return answer;
114 }
115
116 private String encodeServerSide() {
117 if (cookies.size() > 1) {
118 throw new IllegalStateException(
119 "encode() can encode only one cookie on server mode: " + cookies.size() + " cookies added");
120 }
121
122 Cookie cookie = cookies.isEmpty() ? null : cookies.iterator().next();
123 ServerCookieEncoder encoder = strict ? ServerCookieEncoder.STRICT : ServerCookieEncoder.LAX;
124 return encoder.encode(cookie);
125 }
126
127 private String encodeClientSide() {
128 ClientCookieEncoder encoder = strict ? ClientCookieEncoder.STRICT : ClientCookieEncoder.LAX;
129 return encoder.encode(cookies);
130 }
131 }