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.impl;
29
30 import org.apache.http.ConnectionReuseStrategy;
31 import org.apache.http.Header;
32 import org.apache.http.HeaderIterator;
33 import org.apache.http.HttpHeaders;
34 import org.apache.http.HttpRequest;
35 import org.apache.http.HttpResponse;
36 import org.apache.http.HttpStatus;
37 import org.apache.http.HttpVersion;
38 import org.apache.http.ParseException;
39 import org.apache.http.ProtocolVersion;
40 import org.apache.http.TokenIterator;
41 import org.apache.http.annotation.Contract;
42 import org.apache.http.annotation.ThreadingBehavior;
43 import org.apache.http.message.BasicTokenIterator;
44 import org.apache.http.protocol.HTTP;
45 import org.apache.http.protocol.HttpContext;
46 import org.apache.http.protocol.HttpCoreContext;
47 import org.apache.http.util.Args;
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 @Contract(threading = ThreadingBehavior.IMMUTABLE)
68 public class DefaultConnectionReuseStrategy implements ConnectionReuseStrategy {
69
70 public static final DefaultConnectionReuseStrategyml#DefaultConnectionReuseStrategy">DefaultConnectionReuseStrategy INSTANCE = new DefaultConnectionReuseStrategy();
71
72 public DefaultConnectionReuseStrategy() {
73 super();
74 }
75
76
77 @Override
78 public boolean keepAlive(final HttpResponse response,
79 final HttpContext context) {
80 Args.notNull(response, "HTTP response");
81 Args.notNull(context, "HTTP context");
82
83
84
85
86 if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NO_CONTENT) {
87 final Header clh = response.getFirstHeader(HTTP.CONTENT_LEN);
88 if (clh != null) {
89 try {
90 final int contentLen = Integer.parseInt(clh.getValue());
91 if (contentLen > 0) {
92 return false;
93 }
94 } catch (final NumberFormatException ex) {
95
96 }
97 }
98
99 final Header teh = response.getFirstHeader(HTTP.TRANSFER_ENCODING);
100 if (teh != null) {
101 return false;
102 }
103 }
104
105 final HttpRequest../../org/apache/http/HttpRequest.html#HttpRequest">HttpRequest request = (HttpRequest) context.getAttribute(HttpCoreContext.HTTP_REQUEST);
106 if (request != null) {
107 try {
108 final TokenIterator ti = new BasicTokenIterator(request.headerIterator(HttpHeaders.CONNECTION));
109 while (ti.hasNext()) {
110 final String token = ti.nextToken();
111 if (HTTP.CONN_CLOSE.equalsIgnoreCase(token)) {
112 return false;
113 }
114 }
115 } catch (final ParseException px) {
116
117 return false;
118 }
119 }
120
121
122
123 final ProtocolVersion ver = response.getStatusLine().getProtocolVersion();
124 final Header teh = response.getFirstHeader(HTTP.TRANSFER_ENCODING);
125 if (teh != null) {
126 if (!HTTP.CHUNK_CODING.equalsIgnoreCase(teh.getValue())) {
127 return false;
128 }
129 } else {
130 if (canResponseHaveBody(request, response)) {
131 final Header[] clhs = response.getHeaders(HTTP.CONTENT_LEN);
132
133 if (clhs.length == 1) {
134 final Header clh = clhs[0];
135 try {
136 final long contentLen = Long.parseLong(clh.getValue());
137 if (contentLen < 0) {
138 return false;
139 }
140 } catch (final NumberFormatException ex) {
141 return false;
142 }
143 } else {
144 return false;
145 }
146 }
147 }
148
149
150
151
152 HeaderIterator headerIterator = response.headerIterator(HTTP.CONN_DIRECTIVE);
153 if (!headerIterator.hasNext()) {
154 headerIterator = response.headerIterator("Proxy-Connection");
155 }
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180 if (headerIterator.hasNext()) {
181 try {
182 final TokenIterator ti = new BasicTokenIterator(headerIterator);
183 boolean keepalive = false;
184 while (ti.hasNext()) {
185 final String token = ti.nextToken();
186 if (HTTP.CONN_CLOSE.equalsIgnoreCase(token)) {
187 return false;
188 } else if (HTTP.CONN_KEEP_ALIVE.equalsIgnoreCase(token)) {
189
190 keepalive = true;
191 }
192 }
193 if (keepalive) {
194 return true;
195
196 }
197
198 } catch (final ParseException px) {
199
200 return false;
201 }
202 }
203
204
205 return !ver.lessEquals(HttpVersion.HTTP_1_0);
206 }
207
208
209
210
211
212
213
214
215
216
217
218 protected TokenIterator createTokenIterator(final HeaderIterator hit) {
219 return new BasicTokenIterator(hit);
220 }
221
222 private boolean canResponseHaveBody(final HttpRequest request, final HttpResponse response) {
223 if (request != null && request.getRequestLine().getMethod().equalsIgnoreCase("HEAD")) {
224 return false;
225 }
226 final int status = response.getStatusLine().getStatusCode();
227 return status >= HttpStatus.SC_OK
228 && status != HttpStatus.SC_NO_CONTENT
229 && status != HttpStatus.SC_NOT_MODIFIED
230 && status != HttpStatus.SC_RESET_CONTENT;
231 }
232
233 }