1 /*
2 * Copyright 2015 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.cookie;
17
18 import static org.jboss.netty.handler.codec.http.cookie.CookieUtil.*;
19
20 import java.util.Iterator;
21
22 import org.jboss.netty.handler.codec.http.HttpRequest;
23
24 /**
25 * A <a href="http://tools.ietf.org/html/rfc6265">RFC6265</a> compliant cookie encoder to be used client side,
26 * so only name=value pairs are sent.
27 *
28 * User-Agents are not supposed to interpret cookies, so, if present, {@link Cookie#rawValue()} will be used.
29 * Otherwise, {@link Cookie#value()} will be used unquoted.
30 *
31 * Note that multiple cookies are supposed to be sent at once in a single "Cookie" header.
32 *
33 * <pre>
34 * // Example
35 * {@link HttpRequest} req = ...;
36 * res.setHeader("Cookie", {@link ClientCookieEncoder}.encode("JSESSIONID", "1234"));
37 * </pre>
38 *
39 * @see ClientCookieDecoder
40 */
41 public final class ClientCookieEncoder extends CookieEncoder {
42
43 /**
44 * Strict encoder that validates that name and value chars are in the valid scope
45 * defined in RFC6265
46 */
47 public static final ClientCookieEncoder STRICT = new ClientCookieEncoder(true);
48
49 /**
50 * Lax instance that doesn't validate name and value
51 */
52 public static final ClientCookieEncoder LAX = new ClientCookieEncoder(false);
53
54 private ClientCookieEncoder(boolean strict) {
55 super(strict);
56 }
57
58 /**
59 * Encodes the specified cookie into a Cookie header value.
60 *
61 * @param name the cookie name
62 * @param value the cookie value
63 * @return a Rfc6265 style Cookie header value
64 */
65 public String encode(String name, String value) {
66 return encode(new DefaultCookie(name, value));
67 }
68
69 /**
70 * Encodes the specified cookie into a Cookie header value.
71 *
72 * @param specified the cookie
73 * @return a Rfc6265 style Cookie header value
74 */
75 public String encode(Cookie cookie) {
76 if (cookie == null) {
77 throw new NullPointerException("cookie");
78 }
79 StringBuilder buf = new StringBuilder();
80 encode(buf, cookie);
81 return stripTrailingSeparator(buf);
82 }
83
84 /**
85 * Encodes the specified cookies into a single Cookie header value.
86 *
87 * @param cookies some cookies
88 * @return a Rfc6265 style Cookie header value, null if no cookies are passed.
89 */
90 public String encode(Cookie... cookies) {
91 if (cookies == null) {
92 throw new NullPointerException("cookies");
93 }
94 if (cookies.length == 0) {
95 return null;
96 }
97
98 StringBuilder buf = new StringBuilder();
99 for (Cookie c : cookies) {
100 if (c == null) {
101 break;
102 }
103
104 encode(buf, c);
105 }
106 return stripTrailingSeparatorOrNull(buf);
107 }
108
109 /**
110 * Encodes the specified cookies into a single Cookie header value.
111 *
112 * @param cookies some cookies
113 * @return a Rfc6265 style Cookie header value, null if no cookies are passed.
114 */
115 public String encode(Iterable<? extends Cookie> cookies) {
116 if (cookies == null) {
117 throw new NullPointerException("cookies");
118 }
119 Iterator<? extends Cookie> cookiesIt = cookies.iterator();
120 if (!cookiesIt.hasNext()) {
121 return null;
122 }
123
124 StringBuilder buf = new StringBuilder();
125 while (cookiesIt.hasNext()) {
126 Cookie c = cookiesIt.next();
127 if (c == null) {
128 break;
129 }
130
131 encode(buf, c);
132 }
133 return stripTrailingSeparatorOrNull(buf);
134 }
135
136 private void encode(StringBuilder buf, Cookie c) {
137 final String name = c.name();
138 final String value = c.value() != null ? c.value() : "";
139
140 validateCookie(name, value);
141
142 if (c.wrap()) {
143 addQuoted(buf, name, value);
144 } else {
145 add(buf, name, value);
146 }
147 }
148 }