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.core5.http.impl;
29
30 import java.util.Iterator;
31
32 import org.apache.hc.core5.annotation.Contract;
33 import org.apache.hc.core5.annotation.ThreadingBehavior;
34 import org.apache.hc.core5.http.ConnectionReuseStrategy;
35 import org.apache.hc.core5.http.Header;
36 import org.apache.hc.core5.http.HeaderElements;
37 import org.apache.hc.core5.http.HttpHeaders;
38 import org.apache.hc.core5.http.HttpRequest;
39 import org.apache.hc.core5.http.HttpResponse;
40 import org.apache.hc.core5.http.HttpStatus;
41 import org.apache.hc.core5.http.HttpVersion;
42 import org.apache.hc.core5.http.ProtocolVersion;
43 import org.apache.hc.core5.http.message.BasicTokenIterator;
44 import org.apache.hc.core5.http.message.MessageSupport;
45 import org.apache.hc.core5.http.protocol.HttpContext;
46 import org.apache.hc.core5.util.Args;
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 @Contract(threading = ThreadingBehavior.IMMUTABLE)
69 public class DefaultConnectionReuseStrategy implements ConnectionReuseStrategy {
70
71 public static final DefaultConnectionReuseStrategyeuseStrategy.html#DefaultConnectionReuseStrategy">DefaultConnectionReuseStrategy INSTANCE = new DefaultConnectionReuseStrategy();
72
73 public DefaultConnectionReuseStrategy() {
74 super();
75 }
76
77
78 @Override
79 public boolean keepAlive(
80 final HttpRequest request, final HttpResponse response, final HttpContext context) {
81 Args.notNull(response, "HTTP response");
82
83 if (request != null) {
84 final Iterator<String> ti = new BasicTokenIterator(request.headerIterator(HttpHeaders.CONNECTION));
85 while (ti.hasNext()) {
86 final String token = ti.next();
87 if (HeaderElements.CLOSE.equalsIgnoreCase(token)) {
88 return false;
89 }
90 }
91 }
92
93
94
95
96 if (response.getCode() == HttpStatus.SC_NO_CONTENT) {
97 final Header clh = response.getFirstHeader(HttpHeaders.CONTENT_LENGTH);
98 if (clh != null) {
99 try {
100 final long contentLen = Long.parseLong(clh.getValue());
101 if (contentLen > 0) {
102 return false;
103 }
104 } catch (final NumberFormatException ex) {
105
106 }
107 }
108 if (response.containsHeader(HttpHeaders.TRANSFER_ENCODING)) {
109 return false;
110 }
111 }
112
113
114
115 final Header teh = response.getFirstHeader(HttpHeaders.TRANSFER_ENCODING);
116 if (teh != null) {
117 if (!HeaderElements.CHUNKED_ENCODING.equalsIgnoreCase(teh.getValue())) {
118 return false;
119 }
120 } else {
121 final String method = request != null ? request.getMethod() : null;
122 if (MessageSupport.canResponseHaveBody(method, response)
123 && response.countHeaders(HttpHeaders.CONTENT_LENGTH) != 1) {
124 return false;
125 }
126 }
127
128
129
130
131 Iterator<Header> headerIterator = response.headerIterator(HttpHeaders.CONNECTION);
132 if (!headerIterator.hasNext()) {
133 headerIterator = response.headerIterator("Proxy-Connection");
134 }
135
136 final ProtocolVersion ver = context.getProtocolVersion();
137 if (headerIterator.hasNext()) {
138 if (ver.greaterEquals(HttpVersion.HTTP_1_1)) {
139 final Iterator<String> it = new BasicTokenIterator(headerIterator);
140 while (it.hasNext()) {
141 final String token = it.next();
142 if (HeaderElements.CLOSE.equalsIgnoreCase(token)) {
143 return false;
144 }
145 }
146 return true;
147 }
148 final Iterator<String> it = new BasicTokenIterator(headerIterator);
149 while (it.hasNext()) {
150 final String token = it.next();
151 if (HeaderElements.KEEP_ALIVE.equalsIgnoreCase(token)) {
152 return true;
153 }
154 }
155 return false;
156 }
157 return ver.greaterEquals(HttpVersion.HTTP_1_1);
158 }
159
160 }