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.hc.client5.http.protocol;
29
30 import java.io.IOException;
31 import java.util.ArrayList;
32 import java.util.Date;
33 import java.util.List;
34
35 import org.apache.hc.client5.http.RouteInfo;
36 import org.apache.hc.client5.http.cookie.StandardCookieSpec;
37 import org.apache.hc.client5.http.config.RequestConfig;
38 import org.apache.hc.client5.http.cookie.Cookie;
39 import org.apache.hc.client5.http.cookie.CookieOrigin;
40 import org.apache.hc.client5.http.cookie.CookieSpec;
41 import org.apache.hc.client5.http.cookie.CookieSpecFactory;
42 import org.apache.hc.client5.http.cookie.CookieStore;
43 import org.apache.hc.core5.annotation.Contract;
44 import org.apache.hc.core5.annotation.ThreadingBehavior;
45 import org.apache.hc.core5.http.EntityDetails;
46 import org.apache.hc.core5.http.Header;
47 import org.apache.hc.core5.http.HttpException;
48 import org.apache.hc.core5.http.HttpRequest;
49 import org.apache.hc.core5.http.HttpRequestInterceptor;
50 import org.apache.hc.core5.http.config.Lookup;
51 import org.apache.hc.core5.http.protocol.HttpContext;
52 import org.apache.hc.core5.net.URIAuthority;
53 import org.apache.hc.core5.util.Args;
54 import org.apache.hc.core5.util.TextUtils;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57
58
59
60
61
62
63
64
65 @Contract(threading = ThreadingBehavior.STATELESS)
66 public class RequestAddCookies implements HttpRequestInterceptor {
67
68 private static final Logger LOG = LoggerFactory.getLogger(RequestAddCookies.class);
69
70 public RequestAddCookies() {
71 super();
72 }
73
74 @Override
75 public void process(final HttpRequest request, final EntityDetails entity, final HttpContext context)
76 throws HttpException, IOException {
77 Args.notNull(request, "HTTP request");
78 Args.notNull(context, "HTTP context");
79
80 final String method = request.getMethod();
81 if (method.equalsIgnoreCase("CONNECT") || method.equalsIgnoreCase("TRACE")) {
82 return;
83 }
84
85 final HttpClientContext clientContext = HttpClientContext.adapt(context);
86
87
88 final CookieStore cookieStore = clientContext.getCookieStore();
89 if (cookieStore == null) {
90 LOG.debug("Cookie store not specified in HTTP context");
91 return;
92 }
93
94
95 final Lookup<CookieSpecFactory> registry = clientContext.getCookieSpecRegistry();
96 if (registry == null) {
97 LOG.debug("CookieSpec registry not specified in HTTP context");
98 return;
99 }
100
101
102 final RouteInfo route = clientContext.getHttpRoute();
103 if (route == null) {
104 LOG.debug("Connection route not set in the context");
105 return;
106 }
107
108 final RequestConfig config = clientContext.getRequestConfig();
109 String cookieSpecName = config.getCookieSpec();
110 if (cookieSpecName == null) {
111 cookieSpecName = StandardCookieSpec.STRICT;
112 }
113 if (LOG.isDebugEnabled()) {
114 LOG.debug("Cookie spec selected: {}", cookieSpecName);
115 }
116
117 final URIAuthority authority = request.getAuthority();
118 String path = request.getPath();
119 if (TextUtils.isEmpty(path)) {
120 path = "/";
121 }
122 String hostName = authority != null ? authority.getHostName() : null;
123 if (hostName == null) {
124 hostName = route.getTargetHost().getHostName();
125 }
126 int port = authority != null ? authority.getPort() : -1;
127 if (port < 0) {
128 port = route.getTargetHost().getPort();
129 }
130 final CookieOriginCookieOrigin.html#CookieOrigin">CookieOrigin cookieOrigin = new CookieOrigin(hostName, port, path, route.isSecure());
131
132
133 final CookieSpecFactory factory = registry.lookup(cookieSpecName);
134 if (factory == null) {
135 if (LOG.isDebugEnabled()) {
136 LOG.debug("Unsupported cookie spec: {}", cookieSpecName);
137 }
138
139 return;
140 }
141 final CookieSpec cookieSpec = factory.create(clientContext);
142
143 final List<Cookie> cookies = cookieStore.getCookies();
144
145 final List<Cookie> matchedCookies = new ArrayList<>();
146 final Date now = new Date();
147 boolean expired = false;
148 for (final Cookie cookie : cookies) {
149 if (!cookie.isExpired(now)) {
150 if (cookieSpec.match(cookie, cookieOrigin)) {
151 if (LOG.isDebugEnabled()) {
152 LOG.debug("Cookie {} match {}", cookie, cookieOrigin);
153 }
154 matchedCookies.add(cookie);
155 }
156 } else {
157 if (LOG.isDebugEnabled()) {
158 LOG.debug("Cookie {} expired", cookie);
159 }
160 expired = true;
161 }
162 }
163
164
165
166 if (expired) {
167 cookieStore.clearExpired(now);
168 }
169
170 if (!matchedCookies.isEmpty()) {
171 final List<Header> headers = cookieSpec.formatCookies(matchedCookies);
172 for (final Header header : headers) {
173 request.addHeader(header);
174 }
175 }
176
177
178
179 context.setAttribute(HttpClientContext.COOKIE_SPEC, cookieSpec);
180 context.setAttribute(HttpClientContext.COOKIE_ORIGIN, cookieOrigin);
181 }
182
183 }