View Javadoc

1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.http.client.protocol;
29  
30  import java.io.IOException;
31  import java.util.List;
32  
33  import org.apache.http.annotation.Immutable;
34  
35  import org.apache.commons.logging.Log;
36  import org.apache.commons.logging.LogFactory;
37  import org.apache.http.Header;
38  import org.apache.http.HeaderIterator;
39  import org.apache.http.HttpException;
40  import org.apache.http.HttpResponse;
41  import org.apache.http.HttpResponseInterceptor;
42  import org.apache.http.client.CookieStore;
43  import org.apache.http.cookie.Cookie;
44  import org.apache.http.cookie.CookieOrigin;
45  import org.apache.http.cookie.CookieSpec;
46  import org.apache.http.cookie.MalformedCookieException;
47  import org.apache.http.cookie.SM;
48  import org.apache.http.protocol.HttpContext;
49  
50  /**
51   * Response interceptor that populates the current {@link CookieStore} with data
52   * contained in response cookies received in the given the HTTP response.
53   *
54   * @since 4.0
55   */
56  @Immutable
57  public class ResponseProcessCookies implements HttpResponseInterceptor {
58  
59      private final Log log = LogFactory.getLog(getClass());
60  
61      public ResponseProcessCookies() {
62          super();
63      }
64  
65      public void process(final HttpResponse response, final HttpContext context)
66              throws HttpException, IOException {
67          if (response == null) {
68              throw new IllegalArgumentException("HTTP request may not be null");
69          }
70          if (context == null) {
71              throw new IllegalArgumentException("HTTP context may not be null");
72          }
73  
74          // Obtain actual CookieSpec instance
75          CookieSpec cookieSpec = (CookieSpec) context.getAttribute(
76                  ClientContext.COOKIE_SPEC);
77          if (cookieSpec == null) {
78              this.log.debug("Cookie spec not specified in HTTP context");
79              return;
80          }
81          // Obtain cookie store
82          CookieStore cookieStore = (CookieStore) context.getAttribute(
83                  ClientContext.COOKIE_STORE);
84          if (cookieStore == null) {
85              this.log.debug("Cookie store not specified in HTTP context");
86              return;
87          }
88          // Obtain actual CookieOrigin instance
89          CookieOrigin cookieOrigin = (CookieOrigin) context.getAttribute(
90                  ClientContext.COOKIE_ORIGIN);
91          if (cookieOrigin == null) {
92              this.log.debug("Cookie origin not specified in HTTP context");
93              return;
94          }
95          HeaderIterator it = response.headerIterator(SM.SET_COOKIE);
96          processCookies(it, cookieSpec, cookieOrigin, cookieStore);
97  
98          // see if the cookie spec supports cookie versioning.
99          if (cookieSpec.getVersion() > 0) {
100             // process set-cookie2 headers.
101             // Cookie2 will replace equivalent Cookie instances
102             it = response.headerIterator(SM.SET_COOKIE2);
103             processCookies(it, cookieSpec, cookieOrigin, cookieStore);
104         }
105     }
106 
107     private void processCookies(
108             final HeaderIterator iterator,
109             final CookieSpec cookieSpec,
110             final CookieOrigin cookieOrigin,
111             final CookieStore cookieStore) {
112         while (iterator.hasNext()) {
113             Header header = iterator.nextHeader();
114             try {
115                 List<Cookie> cookies = cookieSpec.parse(header, cookieOrigin);
116                 for (Cookie cookie : cookies) {
117                     try {
118                         cookieSpec.validate(cookie, cookieOrigin);
119                         cookieStore.addCookie(cookie);
120 
121                         if (this.log.isDebugEnabled()) {
122                             this.log.debug("Cookie accepted: \""
123                                     + cookie + "\". ");
124                         }
125                     } catch (MalformedCookieException ex) {
126                         if (this.log.isWarnEnabled()) {
127                             this.log.warn("Cookie rejected: \""
128                                     + cookie + "\". " + ex.getMessage());
129                         }
130                     }
131                 }
132             } catch (MalformedCookieException ex) {
133                 if (this.log.isWarnEnabled()) {
134                     this.log.warn("Invalid cookie header: \""
135                             + header + "\". " + ex.getMessage());
136                 }
137             }
138         }
139     }
140 
141 }