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