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  /**
19   * The default {@link Cookie} implementation.
20   */
21  public class DefaultCookie implements Cookie {
22  
23      private final String name;
24      private String value;
25      private boolean wrap;
26      private String domain;
27      private String path;
28      private int maxAge = Integer.MIN_VALUE;
29      private boolean secure;
30      private boolean httpOnly;
31  
32      /**
33       * Creates a new cookie with the specified name and value.
34       */
35      public DefaultCookie(String name, String value) {
36          if (name == null) {
37              throw new NullPointerException("name");
38          }
39          name = name.trim();
40          if (name.length() == 0) {
41              throw new IllegalArgumentException("empty name");
42          }
43  
44          for (int i = 0; i < name.length(); i ++) {
45              char c = name.charAt(i);
46              if (c > 127) {
47                  throw new IllegalArgumentException(
48                          "name contains non-ascii character: " + name);
49              }
50  
51              // Check prohibited characters.
52              switch (c) {
53              case '\t': case '\n': case 0x0b: case '\f': case '\r':
54              case ' ':  case ',':  case ';':  case '=':
55                  throw new IllegalArgumentException(
56                          "name contains one of the following prohibited characters: " +
57                          "=,; \\t\\r\\n\\v\\f: " + name);
58              }
59          }
60  
61          if (name.charAt(0) == '$') {
62              throw new IllegalArgumentException("name starting with '$' not allowed: " + name);
63          }
64  
65          this.name = name;
66          setValue(value);
67      }
68  
69      public String name() {
70          return name;
71      }
72  
73      public String value() {
74          return value;
75      }
76  
77      public void setValue(String value) {
78          if (value == null) {
79              throw new NullPointerException("value");
80          }
81          this.value = value;
82      }
83  
84      public boolean wrap() {
85          return wrap;
86      }
87  
88      public void setWrap(boolean wrap) {
89          this.wrap = wrap;
90      }
91  
92      public String domain() {
93          return domain;
94      }
95  
96      public void setDomain(String domain) {
97          this.domain = validateValue("domain", domain);
98      }
99  
100     public String path() {
101         return path;
102     }
103 
104     public void setPath(String path) {
105         this.path = validateValue("path", path);
106     }
107 
108     public int maxAge() {
109         return maxAge;
110     }
111 
112     public void setMaxAge(int maxAge) {
113         this.maxAge = maxAge;
114     }
115 
116     public boolean isSecure() {
117         return secure;
118     }
119 
120     public void setSecure(boolean secure) {
121         this.secure = secure;
122     }
123 
124     public boolean isHttpOnly() {
125         return httpOnly;
126     }
127 
128     public void setHttpOnly(boolean httpOnly) {
129         this.httpOnly = httpOnly;
130     }
131 
132     @Override
133     public int hashCode() {
134         return name().hashCode();
135     }
136 
137     @Override
138     public boolean equals(Object o) {
139         if (this == o) {
140             return true;
141         }
142 
143         if (!(o instanceof Cookie)) {
144             return false;
145         }
146 
147         Cookie that = (Cookie) o;
148         if (!name().equalsIgnoreCase(that.name())) {
149             return false;
150         }
151 
152         if (path() == null) {
153             if (that.path() != null) {
154                 return false;
155             }
156         } else if (that.path() == null) {
157             return false;
158         } else if (!path().equals(that.path())) {
159             return false;
160         }
161 
162         if (domain() == null) {
163             if (that.domain() != null) {
164                 return false;
165             }
166         } else if (that.domain() == null) {
167             return false;
168         } else {
169             return domain().equalsIgnoreCase(that.domain());
170         }
171 
172         return true;
173     }
174 
175     public int compareTo(Cookie c) {
176         int v = name().compareToIgnoreCase(c.name());
177         if (v != 0) {
178             return v;
179         }
180 
181         if (path() == null) {
182             if (c.path() != null) {
183                 return -1;
184             }
185         } else if (c.path() == null) {
186             return 1;
187         } else {
188             v = path().compareTo(c.path());
189             if (v != 0) {
190                 return v;
191             }
192         }
193 
194         if (domain() == null) {
195             if (c.domain() != null) {
196                 return -1;
197             }
198         } else if (c.domain() == null) {
199             return 1;
200         } else {
201             v = domain().compareToIgnoreCase(c.domain());
202             return v;
203         }
204 
205         return 0;
206     }
207 
208     public String toString() {
209         StringBuilder buf = new StringBuilder()
210             .append(name())
211             .append('=')
212             .append(value());
213         if (domain() != null) {
214             buf.append(", domain=")
215                .append(domain());
216         }
217         if (path() != null) {
218             buf.append(", path=")
219                .append(path());
220         }
221         if (maxAge() >= 0) {
222             buf.append(", maxAge=")
223                .append(maxAge())
224                .append('s');
225         }
226         if (isSecure()) {
227             buf.append(", secure");
228         }
229         if (isHttpOnly()) {
230             buf.append(", HTTPOnly");
231         }
232         return buf.toString();
233     }
234 
235     protected String validateValue(String name, String value) {
236         if (value == null) {
237             return null;
238         }
239         value = value.trim();
240         if (value.length() == 0) {
241             return null;
242         }
243         for (int i = 0; i < value.length(); i ++) {
244             char c = value.charAt(i);
245             switch (c) {
246             case '\r': case '\n': case '\f': case 0x0b: case ';':
247                 throw new IllegalArgumentException(
248                         name + " contains one of the following prohibited characters: " +
249                         ";\\r\\n\\f\\v (" + value + ')');
250             }
251         }
252         return value;
253     }
254 }