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 localContext)
71 throws HttpException, IOException {
72 Args.notNull(response, "HTTP response");
73 Args.notNull(localContext, "HTTP context");
74
75 final HttpCoreContext context = HttpCoreContext.cast(localContext);
76
77 final int status = response.getCode();
78 if (status == HttpStatus.SC_BAD_REQUEST ||
79 status == HttpStatus.SC_REQUEST_TIMEOUT ||
80 status == HttpStatus.SC_LENGTH_REQUIRED ||
81 status == HttpStatus.SC_REQUEST_TOO_LONG ||
82 status == HttpStatus.SC_REQUEST_URI_TOO_LONG ||
83 status == HttpStatus.SC_SERVICE_UNAVAILABLE ||
84 status == HttpStatus.SC_NOT_IMPLEMENTED) {
85 response.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
86 return;
87 }
88 if (!response.containsHeader(HttpHeaders.CONNECTION)) {
89
90
91 final ProtocolVersion ver = context.getProtocolVersion();
92 if (entity != null && entity.getContentLength() < 0 && ver.lessEquals(HttpVersion.HTTP_1_0)) {
93 response.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
94 } else {
95 final HttpRequest request = context.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 }