View Javadoc
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 }