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.protocol;
29
30 import java.io.IOException;
31 import java.util.Iterator;
32
33 import org.apache.hc.core5.annotation.Contract;
34 import org.apache.hc.core5.annotation.ThreadingBehavior;
35 import org.apache.hc.core5.http.EntityDetails;
36 import org.apache.hc.core5.http.HeaderElement;
37 import org.apache.hc.core5.http.HeaderElements;
38 import org.apache.hc.core5.http.HttpException;
39 import org.apache.hc.core5.http.HttpHeaders;
40 import org.apache.hc.core5.http.HttpRequest;
41 import org.apache.hc.core5.http.HttpResponse;
42 import org.apache.hc.core5.http.HttpResponseInterceptor;
43 import org.apache.hc.core5.http.HttpStatus;
44 import org.apache.hc.core5.http.HttpVersion;
45 import org.apache.hc.core5.http.ProtocolVersion;
46 import org.apache.hc.core5.http.message.MessageSupport;
47 import org.apache.hc.core5.util.Args;
48
49
50
51
52
53
54
55
56
57 @Contract(threading = ThreadingBehavior.IMMUTABLE)
58 public class ResponseConnControl implements HttpResponseInterceptor {
59
60 public ResponseConnControl() {
61 super();
62 }
63
64 @Override
65 public void process(final HttpResponse response, final EntityDetails entity, final HttpContext context)
66 throws HttpException, IOException {
67 Args.notNull(response, "HTTP response");
68 Args.notNull(context, "HTTP context");
69
70
71 final int status = response.getCode();
72 if (status == HttpStatus.SC_BAD_REQUEST ||
73 status == HttpStatus.SC_REQUEST_TIMEOUT ||
74 status == HttpStatus.SC_LENGTH_REQUIRED ||
75 status == HttpStatus.SC_REQUEST_TOO_LONG ||
76 status == HttpStatus.SC_REQUEST_URI_TOO_LONG ||
77 status == HttpStatus.SC_SERVICE_UNAVAILABLE ||
78 status == HttpStatus.SC_NOT_IMPLEMENTED) {
79 response.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
80 return;
81 }
82 if (!response.containsHeader(HttpHeaders.CONNECTION)) {
83
84
85 final ProtocolVersion ver = context.getProtocolVersion();
86 if (entity != null && entity.getContentLength() < 0 && ver.lessEquals(HttpVersion.HTTP_1_0)) {
87 response.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
88 } else {
89 final HttpCoreContext coreContext = HttpCoreContext.adapt(context);
90 final HttpRequest request = coreContext.getRequest();
91 boolean closeRequested = false;
92 boolean keepAliveRequested = false;
93 if (request != null) {
94 final Iterator<HeaderElement> it = MessageSupport.iterate(request, HttpHeaders.CONNECTION);
95 while (it.hasNext()) {
96 final HeaderElement he = it.next();
97 if (he.getName().equalsIgnoreCase(HeaderElements.CLOSE)) {
98 closeRequested = true;
99 break;
100 } else if (he.getName().equalsIgnoreCase(HeaderElements.KEEP_ALIVE)) {
101 keepAliveRequested = true;
102 }
103 }
104 }
105 if (closeRequested) {
106 response.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
107 } else {
108 if (response.containsHeader(HttpHeaders.UPGRADE)) {
109 response.addHeader(HttpHeaders.CONNECTION, HeaderElements.UPGRADE);
110 } else {
111 if (keepAliveRequested) {
112 response.addHeader(HttpHeaders.CONNECTION, HeaderElements.KEEP_ALIVE);
113 } else {
114 if (ver.lessEquals(HttpVersion.HTTP_1_0)) {
115 response.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
116 }
117 }
118 }
119 }
120 }
121 }
122 }
123
124 }