1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.http.client.protocol;
29
30 import java.io.IOException;
31 import java.net.URI;
32 import java.net.URISyntaxException;
33 import java.util.ArrayList;
34 import java.util.Date;
35 import java.util.List;
36
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39 import org.apache.http.Header;
40 import org.apache.http.HttpException;
41 import org.apache.http.HttpHost;
42 import org.apache.http.HttpRequest;
43 import org.apache.http.HttpRequestInterceptor;
44 import org.apache.http.annotation.Contract;
45 import org.apache.http.annotation.ThreadingBehavior;
46 import org.apache.http.client.CookieStore;
47 import org.apache.http.client.config.CookieSpecs;
48 import org.apache.http.client.config.RequestConfig;
49 import org.apache.http.client.methods.HttpUriRequest;
50 import org.apache.http.config.Lookup;
51 import org.apache.http.conn.routing.RouteInfo;
52 import org.apache.http.cookie.Cookie;
53 import org.apache.http.cookie.CookieOrigin;
54 import org.apache.http.cookie.CookieSpec;
55 import org.apache.http.cookie.CookieSpecProvider;
56 import org.apache.http.protocol.HttpContext;
57 import org.apache.http.util.Args;
58 import org.apache.http.util.TextUtils;
59
60
61
62
63
64
65
66
67 @Contract(threading = ThreadingBehavior.IMMUTABLE)
68 public class RequestAddCookies implements HttpRequestInterceptor {
69
70 private final Log log = LogFactory.getLog(getClass());
71
72 public RequestAddCookies() {
73 super();
74 }
75
76 @Override
77 public void process(final HttpRequest request, final HttpContext context)
78 throws HttpException, IOException {
79 Args.notNull(request, "HTTP request");
80 Args.notNull(context, "HTTP context");
81
82 final String method = request.getRequestLine().getMethod();
83 if (method.equalsIgnoreCase("CONNECT")) {
84 return;
85 }
86
87 final HttpClientContext clientContext = HttpClientContext.adapt(context);
88
89
90 final CookieStore cookieStore = clientContext.getCookieStore();
91 if (cookieStore == null) {
92 this.log.debug("Cookie store not specified in HTTP context");
93 return;
94 }
95
96
97 final Lookup<CookieSpecProvider> registry = clientContext.getCookieSpecRegistry();
98 if (registry == null) {
99 this.log.debug("CookieSpec registry not specified in HTTP context");
100 return;
101 }
102
103
104 final HttpHost targetHost = clientContext.getTargetHost();
105 if (targetHost == null) {
106 this.log.debug("Target host not set in the context");
107 return;
108 }
109
110
111 final RouteInfo route = clientContext.getHttpRoute();
112 if (route == null) {
113 this.log.debug("Connection route not set in the context");
114 return;
115 }
116
117 final RequestConfig config = clientContext.getRequestConfig();
118 String policy = config.getCookieSpec();
119 if (policy == null) {
120 policy = CookieSpecs.DEFAULT;
121 }
122 if (this.log.isDebugEnabled()) {
123 this.log.debug("CookieSpec selected: " + policy);
124 }
125
126 URI requestURI = null;
127 if (request instanceof HttpUriRequest) {
128 requestURI = ((HttpUriRequest) request).getURI();
129 } else {
130 try {
131 requestURI = new URI(request.getRequestLine().getUri());
132 } catch (final URISyntaxException ignore) {
133 }
134 }
135 final String path = requestURI != null ? requestURI.getPath() : null;
136 final String hostName = targetHost.getHostName();
137 int port = targetHost.getPort();
138 if (port < 0) {
139 port = route.getTargetHost().getPort();
140 }
141
142 final CookieOrigintml#CookieOrigin">CookieOrigin cookieOrigin = new CookieOrigin(
143 hostName,
144 port >= 0 ? port : 0,
145 !TextUtils.isEmpty(path) ? path : "/",
146 route.isSecure());
147
148
149 final CookieSpecProvider provider = registry.lookup(policy);
150 if (provider == null) {
151 if (this.log.isDebugEnabled()) {
152 this.log.debug("Unsupported cookie policy: " + policy);
153 }
154
155 return;
156 }
157 final CookieSpec cookieSpec = provider.create(clientContext);
158
159 final List<Cookie> cookies = cookieStore.getCookies();
160
161 final List<Cookie> matchedCookies = new ArrayList<Cookie>();
162 final Date now = new Date();
163 boolean expired = false;
164 for (final Cookie cookie : cookies) {
165 if (!cookie.isExpired(now)) {
166 if (cookieSpec.match(cookie, cookieOrigin)) {
167 if (this.log.isDebugEnabled()) {
168 this.log.debug("Cookie " + cookie + " match " + cookieOrigin);
169 }
170 matchedCookies.add(cookie);
171 }
172 } else {
173 if (this.log.isDebugEnabled()) {
174 this.log.debug("Cookie " + cookie + " expired");
175 }
176 expired = true;
177 }
178 }
179
180
181
182 if (expired) {
183 cookieStore.clearExpired(now);
184 }
185
186 if (!matchedCookies.isEmpty()) {
187 final List<Header> headers = cookieSpec.formatCookies(matchedCookies);
188 for (final Header header : headers) {
189 request.addHeader(header);
190 }
191 }
192
193 final int ver = cookieSpec.getVersion();
194 if (ver > 0) {
195 final Header header = cookieSpec.getVersionHeader();
196 if (header != null) {
197
198 request.addHeader(header);
199 }
200 }
201
202
203
204 context.setAttribute(HttpClientContext.COOKIE_SPEC, cookieSpec);
205 context.setAttribute(HttpClientContext.COOKIE_ORIGIN, cookieOrigin);
206 }
207
208 }