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.Iterator;
32 import java.util.List;
33
34 import org.apache.hc.client5.http.cookie.Cookie;
35 import org.apache.hc.client5.http.cookie.CookieOrigin;
36 import org.apache.hc.client5.http.cookie.CookieSpec;
37 import org.apache.hc.client5.http.cookie.CookieStore;
38 import org.apache.hc.client5.http.cookie.MalformedCookieException;
39 import org.apache.hc.core5.annotation.Contract;
40 import org.apache.hc.core5.annotation.ThreadingBehavior;
41 import org.apache.hc.core5.http.EntityDetails;
42 import org.apache.hc.core5.http.Header;
43 import org.apache.hc.core5.http.HttpException;
44 import org.apache.hc.core5.http.HttpHeaders;
45 import org.apache.hc.core5.http.HttpResponse;
46 import org.apache.hc.core5.http.HttpResponseInterceptor;
47 import org.apache.hc.core5.http.protocol.HttpContext;
48 import org.apache.hc.core5.util.Args;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52
53
54
55
56
57
58 @Contract(threading = ThreadingBehavior.STATELESS)
59 public class ResponseProcessCookies implements HttpResponseInterceptor {
60
61
62
63
64
65
66 public static final ResponseProcessCookies INSTANCE = new ResponseProcessCookies();
67
68 private static final Logger LOG = LoggerFactory.getLogger(ResponseProcessCookies.class);
69
70 public ResponseProcessCookies() {
71 super();
72 }
73
74 @Override
75 public void process(final HttpResponse response, final EntityDetails entity, final HttpContext context)
76 throws HttpException, IOException {
77 Args.notNull(response, "HTTP request");
78 Args.notNull(context, "HTTP context");
79
80 final HttpClientContext clientContext = HttpClientContext.adapt(context);
81 final String exchangeId = clientContext.getExchangeId();
82
83
84 final CookieSpec cookieSpec = clientContext.getCookieSpec();
85 if (cookieSpec == null) {
86 if (LOG.isDebugEnabled()) {
87 LOG.debug("{} Cookie spec not specified in HTTP context", exchangeId);
88 }
89 return;
90 }
91
92 final CookieStore cookieStore = clientContext.getCookieStore();
93 if (cookieStore == null) {
94 if (LOG.isDebugEnabled()) {
95 LOG.debug("{} Cookie store not specified in HTTP context", exchangeId);
96 }
97 return;
98 }
99
100 final CookieOrigin cookieOrigin = clientContext.getCookieOrigin();
101 if (cookieOrigin == null) {
102 if (LOG.isDebugEnabled()) {
103 LOG.debug("{} Cookie origin not specified in HTTP context", exchangeId);
104 }
105 return;
106 }
107 final Iterator<Header> it = response.headerIterator(HttpHeaders.SET_COOKIE);
108 processCookies(exchangeId, it, cookieSpec, cookieOrigin, cookieStore);
109 }
110
111 private void processCookies(
112 final String exchangeId,
113 final Iterator<Header> iterator,
114 final CookieSpec cookieSpec,
115 final CookieOrigin cookieOrigin,
116 final CookieStore cookieStore) {
117 while (iterator.hasNext()) {
118 final Header header = iterator.next();
119 try {
120 final List<Cookie> cookies = cookieSpec.parse(header, cookieOrigin);
121 for (final Cookie cookie : cookies) {
122 try {
123 cookieSpec.validate(cookie, cookieOrigin);
124 cookieStore.addCookie(cookie);
125
126 if (LOG.isDebugEnabled()) {
127 LOG.debug("{} Cookie accepted [{}]", exchangeId, formatCookie(cookie));
128 }
129 } catch (final MalformedCookieException ex) {
130 if (LOG.isWarnEnabled()) {
131 LOG.warn("{} Cookie rejected [{}] {}", exchangeId, formatCookie(cookie), ex.getMessage());
132 }
133 }
134 }
135 } catch (final MalformedCookieException ex) {
136 if (LOG.isWarnEnabled()) {
137 LOG.warn("{} Invalid cookie header: \"{}\". {}", exchangeId, header, ex.getMessage());
138 }
139 }
140 }
141 }
142
143 private static String formatCookie(final Cookie cookie) {
144 final StringBuilder buf = new StringBuilder();
145 buf.append(cookie.getName());
146 buf.append("=\"");
147 String v = cookie.getValue();
148 if (v != null) {
149 if (v.length() > 100) {
150 v = v.substring(0, 100) + "...";
151 }
152 buf.append(v);
153 }
154 buf.append("\"");
155 buf.append(", domain:");
156 buf.append(cookie.getDomain());
157 buf.append(", path:");
158 buf.append(cookie.getPath());
159 buf.append(", expiry:");
160 buf.append(cookie.getExpiryInstant());
161 return buf.toString();
162 }
163
164 }