View Javadoc

    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 java.util.Collections;
    19  import java.util.Set;
    20  import java.util.TreeSet;
    21
    22
    23
    24  /**
    25   * The default {@link Cookie} implementation.
    26   */
    27  public class DefaultCookie implements Cookie {
    28
    29      private final String name;
    30      private String value;
    31      private String domain;
    32      private String path;
    33      private String comment;
    34      private String commentUrl;
    35      private boolean discard;
    36      private Set<Integer> ports = Collections.emptySet();
    37      private Set<Integer> unmodifiablePorts = ports;
    38      private int maxAge = Integer.MIN_VALUE;
    39      private int version;
    40      private boolean secure;
    41      private boolean httpOnly;
    42
    43      /**
    44       * Creates a new cookie with the specified name and value.
    45       */
    46      public DefaultCookie(String name, String value) {
    47          if (name == null) {
    48              throw new NullPointerException("name");
    49          }
    50          name = name.trim();
    51          if (name.length() == 0) {
    52              throw new IllegalArgumentException("empty name");
    53          }
    54
    55          for (int i = 0; i < name.length(); i ++) {
    56              char c = name.charAt(i);
    57              if (c > 127) {
    58                  throw new IllegalArgumentException(
    59                          "name contains non-ascii character: " + name);
    60              }
    61
    62              // Check prohibited characters.
    63              switch (c) {
    64              case '\t': case '\n': case 0x0b: case '\f': case '\r':
    65              case ' ':  case ',':  case ';':  case '=':
    66                  throw new IllegalArgumentException(
    67                          "name contains one of the following prohibited characters: " +
    68                          "=,; \\t\\r\\n\\v\\f: " + name);
    69              }
    70          }
    71
    72          if (name.charAt(0) == '$') {
    73              throw new IllegalArgumentException("name starting with '$' not allowed: " + name);
    74          }
    75
    76          this.name = name;
    77          setValue(value);
    78      }
    79
    80      public String getName() {
    81          return name;
    82      }
    83
    84      public String getValue() {
    85          return value;
    86      }
    87
    88      public void setValue(String value) {
    89          if (value == null) {
    90              throw new NullPointerException("value");
    91          }
    92          this.value = value;
    93      }
    94
    95      public String getDomain() {
    96          return domain;
    97      }
    98
    99      public void setDomain(String domain) {
    100         this.domain = validateValue("domain", domain);
    101     }
    102
    103     public String getPath() {
    104         return path;
    105     }
    106
    107     public void setPath(String path) {
    108         this.path = validateValue("path", path);
    109     }
    110
    111     public String getComment() {
    112         return comment;
    113     }
    114
    115     public void setComment(String comment) {
    116         this.comment = validateValue("comment", comment);
    117     }
    118
    119     public String getCommentUrl() {
    120         return commentUrl;
    121     }
    122
    123     public void setCommentUrl(String commentUrl) {
    124         this.commentUrl = validateValue("commentUrl", commentUrl);
    125     }
    126
    127     public boolean isDiscard() {
    128         return discard;
    129     }
    130
    131     public void setDiscard(boolean discard) {
    132         this.discard = discard;
    133     }
    134
    135     public Set<Integer> getPorts() {
    136         if (unmodifiablePorts == null) {
    137             unmodifiablePorts = Collections.unmodifiableSet(ports);
    138         }
    139         return unmodifiablePorts;
    140     }
    141
    142     public void setPorts(int... ports) {
    143         if (ports == null) {
    144             throw new NullPointerException("ports");
    145         }
    146
    147         int[] portsCopy = ports.clone();
    148         if (portsCopy.length == 0) {
    149             unmodifiablePorts = this.ports = Collections.emptySet();
    150         } else {
    151             Set<Integer> newPorts = new TreeSet<Integer>();
    152             for (int p: portsCopy) {
    153                 if (p <= 0 || p > 65535) {
    154                     throw new IllegalArgumentException("port out of range: " + p);
    155                 }
    156                 newPorts.add(p);
    157             }
    158             this.ports = newPorts;
    159             unmodifiablePorts = null;
    160         }
    161     }
    162
    163     public void setPorts(Iterable<Integer> ports) {
    164         Set<Integer> newPorts = new TreeSet<Integer>();
    165         for (int p: ports) {
    166             if (p <= 0 || p > 65535) {
    167                 throw new IllegalArgumentException("port out of range: " + p);
    168             }
    169             newPorts.add(p);
    170         }
    171         if (newPorts.isEmpty()) {
    172             unmodifiablePorts = this.ports = Collections.emptySet();
    173         } else {
    174             this.ports = newPorts;
    175             unmodifiablePorts = null;
    176         }
    177     }
    178
    179     public int getMaxAge() {
    180         return maxAge;
    181     }
    182
    183     public void setMaxAge(int maxAge) {
    184         this.maxAge = maxAge;
    185     }
    186
    187     public int getVersion() {
    188         return version;
    189     }
    190
    191     public void setVersion(int version) {
    192         this.version = version;
    193     }
    194
    195     public boolean isSecure() {
    196         return secure;
    197     }
    198
    199     public void setSecure(boolean secure) {
    200         this.secure = secure;
    201     }
    202
    203     public boolean isHttpOnly() {
    204         return httpOnly;
    205     }
    206
    207     public void setHttpOnly(boolean httpOnly) {
    208         this.httpOnly = httpOnly;
    209     }
    210
    211     @Override
    212     public int hashCode() {
    213         return getName().hashCode();
    214     }
    215
    216     @Override
    217     public boolean equals(Object o) {
    218         if (!(o instanceof Cookie)) {
    219             return false;
    220         }
    221
    222         Cookie that = (Cookie) o;
    223         if (!getName().equalsIgnoreCase(that.getName())) {
    224             return false;
    225         }
    226
    227         if (getPath() == null) {
    228             if (that.getPath() != null) {
    229                 return false;
    230             }
    231         } else if (that.getPath() == null) {
    232             return false;
    233         } else if (!getPath().equals(that.getPath())) {
    234             return false;
    235         }
    236
    237         if (getDomain() == null) {
    238             if (that.getDomain() != null) {
    239                 return false;
    240             }
    241         } else if (that.getDomain() == null) {
    242             return false;
    243         } else {
    244             return getDomain().equalsIgnoreCase(that.getDomain());
    245         }
    246
    247         return true;
    248     }
    249
    250     public int compareTo(Cookie c) {
    251         int v;
    252         v = getName().compareToIgnoreCase(c.getName());
    253         if (v != 0) {
    254             return v;
    255         }
    256
    257         if (getPath() == null) {
    258             if (c.getPath() != null) {
    259                 return -1;
    260             }
    261         } else if (c.getPath() == null) {
    262             return 1;
    263         } else {
    264             v = getPath().compareTo(c.getPath());
    265             if (v != 0) {
    266                 return v;
    267             }
    268         }
    269
    270         if (getDomain() == null) {
    271             if (c.getDomain() != null) {
    272                 return -1;
    273             }
    274         } else if (c.getDomain() == null) {
    275             return 1;
    276         } else {
    277             v = getDomain().compareToIgnoreCase(c.getDomain());
    278             return v;
    279         }
    280
    281         return 0;
    282     }
    283
    284     @Override
    285     public String toString() {
    286         StringBuilder buf = new StringBuilder();
    287         buf.append(getName());
    288         buf.append('=');
    289         buf.append(getValue());
    290         if (getDomain() != null) {
    291             buf.append(", domain=");
    292             buf.append(getDomain());
    293         }
    294         if (getPath() != null) {
    295             buf.append(", path=");
    296             buf.append(getPath());
    297         }
    298         if (getComment() != null) {
    299             buf.append(", comment=");
    300             buf.append(getComment());
    301         }
    302         if (getMaxAge() >= 0) {
    303             buf.append(", maxAge=");
    304             buf.append(getMaxAge());
    305             buf.append('s');
    306         }
    307         if (isSecure()) {
    308             buf.append(", secure");
    309         }
    310         if (isHttpOnly()) {
    311             buf.append(", HTTPOnly");
    312         }
    313         return buf.toString();
    314     }
    315
    316     private static String validateValue(String name, String value) {
    317         if (value == null) {
    318             return null;
    319         }
    320         value = value.trim();
    321         if (value.length() == 0) {
    322             return null;
    323         }
    324         for (int i = 0; i < value.length(); i ++) {
    325             char c = value.charAt(i);
    326             switch (c) {
    327             case '\r': case '\n': case '\f': case 0x0b: case ';':
    328                 throw new IllegalArgumentException(
    329                         name + " contains one of the following prohibited characters: " +
    330                         ";\\r\\n\\f\\v (" + value + ')');
    331             }
    332         }
    333         return value;
    334     }
    335 }
    336