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
58
59
60 @Contract(threading = ThreadingBehavior.IMMUTABLE)
61 public class ResponseConnControl implements HttpResponseInterceptor {
62
63 public static final ResponseConnControl INSTANCE = new ResponseConnControl();
64
65 public ResponseConnControl() {
66 super();
67 }
68
69 @Override
70 public void process(final HttpResponse response, final EntityDetails entity, final HttpContext context)
71 throws HttpException, IOException {
72 Args.notNull(response, "HTTP response");
73 Args.notNull(context, "HTTP context");
74
75
76 final int status = response.getCode();
77 if (status == HttpStatus.SC_BAD_REQUEST ||
78 status == HttpStatus.SC_REQUEST_TIMEOUT ||
79 status == HttpStatus.SC_LENGTH_REQUIRED ||
80 status == HttpStatus.SC_REQUEST_TOO_LONG ||
81 status == HttpStatus.SC_REQUEST_URI_TOO_LONG ||
82 status == HttpStatus.SC_SERVICE_UNAVAILABLE ||
83 status == HttpStatus.SC_NOT_IMPLEMENTED) {
84 response.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
85 return;
86 }
87 if (!response.containsHeader(HttpHeaders.CONNECTION)) {
88
89
90 final ProtocolVersion ver = context.getProtocolVersion();
91 if (entity != null && entity.getContentLength() < 0 && ver.lessEquals(HttpVersion.HTTP_1_0)) {
92 response.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
93 } else {
94 final HttpCoreContext coreContext = HttpCoreContext.adapt(context);
95 final HttpRequest request = coreContext.getRequest();
96 boolean closeRequested = false;
97 boolean keepAliveRequested = false;
98 if (request != null) {
99 final Iterator<HeaderElement> it = MessageSupport.iterate(request, HttpHeaders.CONNECTION);
100 while (it.hasNext()) {
101 final HeaderElement he = it.next();
102 if (he.getName().equalsIgnoreCase(HeaderElements.CLOSE)) {
103 closeRequested = true;
104 break;
105 } else if (he.getName().equalsIgnoreCase(HeaderElements.KEEP_ALIVE)) {
106 keepAliveRequested = true;
107 }
108 }
109 }
110 if (closeRequested) {
111 response.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
112 } else {
113 if (response.containsHeader(HttpHeaders.UPGRADE)) {
114 response.addHeader(HttpHeaders.CONNECTION, HeaderElements.UPGRADE);
115 } else {
116 if (keepAliveRequested) {
117 response.addHeader(HttpHeaders.CONNECTION, HeaderElements.KEEP_ALIVE);
118 } else {
119 if (ver.lessEquals(HttpVersion.HTTP_1_0)) {
120 response.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
121 }
122 }
123 }
124 }
125 }
126 }
127 }
128
129 }