1069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/*
2069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/protocol/RequestAddCookies.java $
3069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * $Revision: 673450 $
4069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * $Date: 2008-07-02 10:35:05 -0700 (Wed, 02 Jul 2008) $
5069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
6069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * ====================================================================
7069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one
8069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * or more contributor license agreements.  See the NOTICE file
9069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * distributed with this work for additional information
10069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * regarding copyright ownership.  The ASF licenses this file
11069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to you under the Apache License, Version 2.0 (the
12069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * "License"); you may not use this file except in compliance
13069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * with the License.  You may obtain a copy of the License at
14069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
15069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *   http://www.apache.org/licenses/LICENSE-2.0
16069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
17069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Unless required by applicable law or agreed to in writing,
18069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * software distributed under the License is distributed on an
19069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * KIND, either express or implied.  See the License for the
21069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * specific language governing permissions and limitations
22069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * under the License.
23069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * ====================================================================
24069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
25069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This software consists of voluntary contributions made by many
26069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * individuals on behalf of the Apache Software Foundation.  For more
27069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * information on the Apache Software Foundation, please see
28069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <http://www.apache.org/>.
29069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
30069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */
31069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
32069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpackage org.apache.http.client.protocol;
33069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
34069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.io.IOException;
35069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.net.URI;
36069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.net.URISyntaxException;
37069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.ArrayList;
38069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.List;
39069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
40069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.logging.Log;
41069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.logging.LogFactory;
42069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.Header;
43069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.HttpException;
44069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.HttpHost;
45069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.HttpRequest;
46069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.HttpRequestInterceptor;
47069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.ProtocolException;
48069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.client.CookieStore;
49069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.client.methods.HttpUriRequest;
50069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.client.params.HttpClientParams;
51069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.conn.ManagedClientConnection;
52069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.cookie.Cookie;
53069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.cookie.CookieOrigin;
54069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.cookie.CookieSpec;
55069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.cookie.CookieSpecRegistry;
56069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.protocol.HttpContext;
57069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.protocol.ExecutionContext;
58069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
59069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/**
60069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Request interceptor that matches cookies available in the current
61069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * {@link CookieStore} to the request being executed and generates
62069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * corresponding cookierequest headers.
63069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
64069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
65069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
66069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @version $Revision: 673450 $
67069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
68069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @since 4.0
69d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath *
70d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath * @deprecated Please use {@link java.net.URL#openConnection} instead.
71d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath *     Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
72d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath *     for further details.
73069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */
74d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath@Deprecated
75069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpublic class RequestAddCookies implements HttpRequestInterceptor {
76069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
77069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private final Log log = LogFactory.getLog(getClass());
78069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
79069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public RequestAddCookies() {
80069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        super();
81069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
82069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
83069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public void process(final HttpRequest request, final HttpContext context)
84069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throws HttpException, IOException {
85069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (request == null) {
86069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new IllegalArgumentException("HTTP request may not be null");
87069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
88069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (context == null) {
89069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new IllegalArgumentException("HTTP context may not be null");
90069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
91069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
92069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // Obtain cookie store
93069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        CookieStore cookieStore = (CookieStore) context.getAttribute(
94069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                ClientContext.COOKIE_STORE);
95069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (cookieStore == null) {
96069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            this.log.info("Cookie store not available in HTTP context");
97069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return;
98069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
99069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
100069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // Obtain the registry of cookie specs
101069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        CookieSpecRegistry registry= (CookieSpecRegistry) context.getAttribute(
102069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                ClientContext.COOKIESPEC_REGISTRY);
103069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (registry == null) {
104069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            this.log.info("CookieSpec registry not available in HTTP context");
105069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return;
106069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
107069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
108069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // Obtain the target host (required)
109069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        HttpHost targetHost = (HttpHost) context.getAttribute(
110069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                ExecutionContext.HTTP_TARGET_HOST);
111069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (targetHost == null) {
112069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new IllegalStateException("Target host not specified in HTTP context");
113069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
114069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
115069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // Obtain the client connection (required)
116069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        ManagedClientConnection conn = (ManagedClientConnection) context.getAttribute(
117069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                ExecutionContext.HTTP_CONNECTION);
118069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (conn == null) {
119069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new IllegalStateException("Client connection not specified in HTTP context");
120069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
121069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
122069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        String policy = HttpClientParams.getCookiePolicy(request.getParams());
123069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (this.log.isDebugEnabled()) {
124069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            this.log.debug("CookieSpec selected: " + policy);
125069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
126069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
127069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        URI requestURI;
128069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (request instanceof HttpUriRequest) {
129069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            requestURI = ((HttpUriRequest) request).getURI();
130069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
131069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            try {
132069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                requestURI = new URI(request.getRequestLine().getUri());
133069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } catch (URISyntaxException ex) {
134069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                throw new ProtocolException("Invalid request URI: " +
135069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        request.getRequestLine().getUri(), ex);
136069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
137069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
138069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
139069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        String hostName = targetHost.getHostName();
140069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        int port = targetHost.getPort();
141069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (port < 0) {
142069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            port = conn.getRemotePort();
143069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
144069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
145069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        CookieOrigin cookieOrigin = new CookieOrigin(
146069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                hostName,
147069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                port,
148069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                requestURI.getPath(),
149069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                conn.isSecure());
150069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
151069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // Get an instance of the selected cookie policy
152069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        CookieSpec cookieSpec = registry.getCookieSpec(policy, request.getParams());
153069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // Get all cookies available in the HTTP state
154069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        List<Cookie> cookies = new ArrayList<Cookie>(cookieStore.getCookies());
155069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // Find cookies matching the given origin
156069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        List<Cookie> matchedCookies = new ArrayList<Cookie>();
157069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        for (Cookie cookie : cookies) {
158069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (cookieSpec.match(cookie, cookieOrigin)) {
159069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (this.log.isDebugEnabled()) {
160069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    this.log.debug("Cookie " + cookie + " match " + cookieOrigin);
161069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
162069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                matchedCookies.add(cookie);
163069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
164069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
165069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // Generate Cookie request headers
166069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (!matchedCookies.isEmpty()) {
167069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            List<Header> headers = cookieSpec.formatCookies(matchedCookies);
168069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            for (Header header : headers) {
169069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                request.addHeader(header);
170069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
171069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
172069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
173069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        int ver = cookieSpec.getVersion();
174069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (ver > 0) {
175069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            boolean needVersionHeader = false;
176069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            for (Cookie cookie : matchedCookies) {
177069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (ver != cookie.getVersion()) {
178069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    needVersionHeader = true;
179069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
180069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
181069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
182069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (needVersionHeader) {
183069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                Header header = cookieSpec.getVersionHeader();
184069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (header != null) {
185069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    // Advertise cookie version support
186069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    request.addHeader(header);
187069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
188069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
189069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
190069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
191069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // Stick the CookieSpec and CookieOrigin instances to the HTTP context
192069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // so they could be obtained by the response interceptor
193069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        context.setAttribute(ClientContext.COOKIE_SPEC, cookieSpec);
194069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        context.setAttribute(ClientContext.COOKIE_ORIGIN, cookieOrigin);
195069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
196069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
197069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project}
198