1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.esigate.http;
17
18 import org.apache.http.Header;
19 import org.apache.http.HttpEntityEnclosingRequest;
20 import org.apache.http.HttpHeaders;
21 import org.apache.http.HttpRequest;
22 import org.apache.http.HttpResponse;
23 import org.apache.http.client.methods.CloseableHttpResponse;
24 import org.apache.http.message.BasicHttpResponse;
25 import org.esigate.impl.DriverRequest;
26 import org.esigate.impl.UrlRewriter;
27 import org.esigate.util.FilterList;
28 import org.esigate.util.UriUtils;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32
33
34
35
36
37
38
39
40 public class HeaderManager {
41 private static final Logger LOG = LoggerFactory.getLogger(HeaderManager.class);
42
43 private final FilterList requestHeadersFilterList = new FilterList();
44 private final FilterList responseHeadersFilterList = new FilterList();
45
46 private final UrlRewriter urlRewriter;
47
48
49
50
51
52
53
54 public HeaderManager(UrlRewriter urlRewriter) {
55
56 this.urlRewriter = urlRewriter;
57
58
59
60
61 requestHeadersFilterList.add("*");
62
63 requestHeadersFilterList.remove("Connection");
64 requestHeadersFilterList.remove("Content-Length");
65 requestHeadersFilterList.remove("Cache-control");
66 requestHeadersFilterList.remove("Cookie");
67 requestHeadersFilterList.remove("Host");
68 requestHeadersFilterList.remove("Max-Forwards");
69 requestHeadersFilterList.remove("Pragma");
70 requestHeadersFilterList.remove("Proxy-Authorization");
71 requestHeadersFilterList.remove("TE");
72 requestHeadersFilterList.remove("Trailer");
73 requestHeadersFilterList.remove("Transfer-Encoding");
74 requestHeadersFilterList.remove("Upgrade");
75
76
77 responseHeadersFilterList.add("*");
78
79 responseHeadersFilterList.remove("Connection");
80 responseHeadersFilterList.remove("Content-Length");
81 responseHeadersFilterList.remove("Content-MD5");
82 responseHeadersFilterList.remove("Date");
83 responseHeadersFilterList.remove("Keep-Alive");
84 responseHeadersFilterList.remove("Proxy-Authenticate");
85 responseHeadersFilterList.remove("Set-Cookie");
86 responseHeadersFilterList.remove("Trailer");
87 responseHeadersFilterList.remove("Transfer-Encoding");
88 }
89
90 protected boolean isForwardedRequestHeader(String headerName) {
91 return requestHeadersFilterList.contains(headerName);
92 }
93
94 protected boolean isForwardedResponseHeader(String headerName) {
95 return responseHeadersFilterList.contains(headerName);
96 }
97
98
99
100
101
102
103
104
105
106
107
108 public void copyHeaders(DriverRequest originalRequest, HttpRequest httpRequest) {
109 String baseUrl = originalRequest.getBaseUrl().toString();
110 String visibleBaseUrl = originalRequest.getVisibleBaseUrl();
111 for (Header header : originalRequest.getOriginalRequest().getAllHeaders()) {
112 String name = header.getName();
113
114 if (HttpHeaders.REFERER.equalsIgnoreCase(name) && isForwardedRequestHeader(HttpHeaders.REFERER)) {
115 String value = header.getValue();
116 value = urlRewriter.rewriteReferer(value, baseUrl, visibleBaseUrl);
117 httpRequest.addHeader(name, value);
118
119 } else if (isForwardedRequestHeader(name)) {
120 httpRequest.addHeader(header);
121 }
122 }
123
124 String remoteAddr = originalRequest.getOriginalRequest().getRemoteAddr();
125
126 if (remoteAddr != null) {
127 String forwardedFor = null;
128 if (httpRequest.containsHeader("X-Forwarded-For")) {
129 forwardedFor = httpRequest.getFirstHeader("X-Forwarded-For").getValue();
130 }
131
132 if (forwardedFor == null) {
133 forwardedFor = remoteAddr;
134 } else {
135 forwardedFor = forwardedFor + ", " + remoteAddr;
136 }
137
138 httpRequest.setHeader("X-Forwarded-For", forwardedFor);
139 }
140
141
142 if (!httpRequest.containsHeader("X-Forwarded-Proto")) {
143 httpRequest.addHeader("X-Forwarded-Proto",
144 UriUtils.extractScheme(originalRequest.getOriginalRequest().getRequestLine().getUri()));
145 }
146 }
147
148
149
150
151
152
153
154
155
156
157
158
159 public CloseableHttpResponse copyHeaders(OutgoingRequest outgoingRequest,
160 HttpEntityEnclosingRequest incomingRequest, HttpResponse httpClientResponse) {
161 HttpResponse result = new BasicHttpResponse(httpClientResponse.getStatusLine());
162 result.setEntity(httpClientResponse.getEntity());
163 String originalUri = incomingRequest.getRequestLine().getUri();
164 String baseUrl = outgoingRequest.getBaseUrl().toString();
165 String visibleBaseUrl = outgoingRequest.getOriginalRequest().getVisibleBaseUrl();
166 for (Header header : httpClientResponse.getAllHeaders()) {
167 String name = header.getName();
168 String value = header.getValue();
169 try {
170
171
172 if (!HttpHeaders.CONTENT_ENCODING.equalsIgnoreCase(name)) {
173 if (isForwardedResponseHeader(name)) {
174
175 if (HttpHeaders.LOCATION.equalsIgnoreCase(name)
176 || HttpHeaders.CONTENT_LOCATION.equalsIgnoreCase(name)) {
177
178 value = urlRewriter.rewriteUrl(value, originalUri, baseUrl, visibleBaseUrl, true);
179 value = HttpResponseUtils.removeSessionId(value, httpClientResponse);
180 result.addHeader(name, value);
181 } else if ("Link".equalsIgnoreCase(name)) {
182
183
184
185 if (value.startsWith("<") && value.contains(">")) {
186 String urlValue = value.substring(1, value.indexOf(">"));
187
188 String targetUrlValue =
189 urlRewriter.rewriteUrl(urlValue, originalUri, baseUrl, visibleBaseUrl, true);
190 targetUrlValue = HttpResponseUtils.removeSessionId(targetUrlValue, httpClientResponse);
191
192 value = value.replace("<" + urlValue + ">", "<" + targetUrlValue + ">");
193 }
194
195 result.addHeader(name, value);
196
197 } else if ("Refresh".equalsIgnoreCase(name)) {
198
199
200 int urlPosition = value.indexOf("url=");
201 if (urlPosition >= 0) {
202 value = urlRewriter.rewriteRefresh(value, originalUri, baseUrl, visibleBaseUrl);
203 value = HttpResponseUtils.removeSessionId(value, httpClientResponse);
204 }
205 result.addHeader(name, value);
206 } else if ("P3p".equalsIgnoreCase(name)) {
207
208
209
210 result.addHeader(name, value);
211 } else {
212 result.addHeader(header.getName(), header.getValue());
213 }
214 }
215 }
216 } catch (Exception e1) {
217
218
219
220 LOG.error("Error while copying headers", e1);
221 result.addHeader("X-Esigate-Error", "Error processing header " + name + ": " + value);
222 }
223 }
224 return BasicCloseableHttpResponse.adapt(result);
225 }
226 }