• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/RFC2965PortAttributeHandler.java $
3  * $Revision: 590695 $
4  * $Date: 2007-10-31 07:55:41 -0700 (Wed, 31 Oct 2007) $
5  *
6  * ====================================================================
7  * Licensed to the Apache Software Foundation (ASF) under one
8  * or more contributor license agreements.  See the NOTICE file
9  * distributed with this work for additional information
10  * regarding copyright ownership.  The ASF licenses this file
11  * to you under the Apache License, Version 2.0 (the
12  * "License"); you may not use this file except in compliance
13  * with the License.  You may obtain a copy of the License at
14  *
15  *   http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing,
18  * software distributed under the License is distributed on an
19  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20  * KIND, either express or implied.  See the License for the
21  * specific language governing permissions and limitations
22  * under the License.
23  * ====================================================================
24  *
25  * This software consists of voluntary contributions made by many
26  * individuals on behalf of the Apache Software Foundation.  For more
27  * information on the Apache Software Foundation, please see
28  * <http://www.apache.org/>.
29  *
30  */
31 
32 package org.apache.http.impl.cookie;
33 
34 import java.util.StringTokenizer;
35 
36 import org.apache.http.cookie.ClientCookie;
37 import org.apache.http.cookie.Cookie;
38 import org.apache.http.cookie.CookieAttributeHandler;
39 import org.apache.http.cookie.CookieOrigin;
40 import org.apache.http.cookie.MalformedCookieException;
41 import org.apache.http.cookie.SetCookie;
42 import org.apache.http.cookie.SetCookie2;
43 
44 /**
45  * <tt>"Port"</tt> cookie attribute handler for RFC 2965 cookie spec.
46  */
47 public class RFC2965PortAttributeHandler implements CookieAttributeHandler {
48 
RFC2965PortAttributeHandler()49     public RFC2965PortAttributeHandler() {
50         super();
51     }
52 
53     /**
54      * Parses the given Port attribute value (e.g. "8000,8001,8002")
55      * into an array of ports.
56      *
57      * @param portValue port attribute value
58      * @return parsed array of ports
59      * @throws MalformedCookieException if there is a problem in
60      *          parsing due to invalid portValue.
61      */
parsePortAttribute(final String portValue)62     private static int[] parsePortAttribute(final String portValue)
63             throws MalformedCookieException {
64         StringTokenizer st = new StringTokenizer(portValue, ",");
65         int[] ports = new int[st.countTokens()];
66         try {
67             int i = 0;
68             while(st.hasMoreTokens()) {
69                 ports[i] = Integer.parseInt(st.nextToken().trim());
70                 if (ports[i] < 0) {
71                   throw new MalformedCookieException ("Invalid Port attribute.");
72                 }
73                 ++i;
74             }
75         } catch (NumberFormatException e) {
76             throw new MalformedCookieException ("Invalid Port "
77                                                 + "attribute: " + e.getMessage());
78         }
79         return ports;
80     }
81 
82     /**
83      * Returns <tt>true</tt> if the given port exists in the given
84      * ports list.
85      *
86      * @param port port of host where cookie was received from or being sent to.
87      * @param ports port list
88      * @return true returns <tt>true</tt> if the given port exists in
89      *         the given ports list; <tt>false</tt> otherwise.
90      */
portMatch(int port, int[] ports)91     private static boolean portMatch(int port, int[] ports) {
92         boolean portInList = false;
93         for (int i = 0, len = ports.length; i < len; i++) {
94             if (port == ports[i]) {
95                 portInList = true;
96                 break;
97             }
98         }
99         return portInList;
100     }
101 
102     /**
103      * Parse cookie port attribute.
104      */
parse(final SetCookie cookie, final String portValue)105     public void parse(final SetCookie cookie, final String portValue)
106             throws MalformedCookieException {
107         if (cookie == null) {
108             throw new IllegalArgumentException("Cookie may not be null");
109         }
110         if (cookie instanceof SetCookie2) {
111             SetCookie2 cookie2 = (SetCookie2) cookie;
112             if (portValue != null && portValue.trim().length() > 0) {
113                 int[] ports = parsePortAttribute(portValue);
114                 cookie2.setPorts(ports);
115             }
116         }
117     }
118 
119     /**
120      * Validate cookie port attribute. If the Port attribute was specified
121      * in header, the request port must be in cookie's port list.
122      */
validate(final Cookie cookie, final CookieOrigin origin)123     public void validate(final Cookie cookie, final CookieOrigin origin)
124             throws MalformedCookieException {
125         if (cookie == null) {
126             throw new IllegalArgumentException("Cookie may not be null");
127         }
128         if (origin == null) {
129             throw new IllegalArgumentException("Cookie origin may not be null");
130         }
131         int port = origin.getPort();
132         if (cookie instanceof ClientCookie
133                 && ((ClientCookie) cookie).containsAttribute(ClientCookie.PORT_ATTR)) {
134             if (!portMatch(port, cookie.getPorts())) {
135                 throw new MalformedCookieException(
136                         "Port attribute violates RFC 2965: "
137                         + "Request port not found in cookie's port list.");
138             }
139         }
140     }
141 
142     /**
143      * Match cookie port attribute. If the Port attribute is not specified
144      * in header, the cookie can be sent to any port. Otherwise, the request port
145      * must be in the cookie's port list.
146      */
match(final Cookie cookie, final CookieOrigin origin)147     public boolean match(final Cookie cookie, final CookieOrigin origin) {
148         if (cookie == null) {
149             throw new IllegalArgumentException("Cookie may not be null");
150         }
151         if (origin == null) {
152             throw new IllegalArgumentException("Cookie origin may not be null");
153         }
154         int port = origin.getPort();
155         if (cookie instanceof ClientCookie
156                 && ((ClientCookie) cookie).containsAttribute(ClientCookie.PORT_ATTR)) {
157             if (cookie.getPorts() == null) {
158                 // Invalid cookie state: port not specified
159                 return false;
160             }
161             if (!portMatch(port, cookie.getPorts())) {
162                 return false;
163             }
164         }
165         return true;
166     }
167 
168 }
169