1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.proxy;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.net.URI;
24 import java.nio.ByteBuffer;
25 import java.util.concurrent.TimeUnit;
26
27 import javax.servlet.AsyncContext;
28 import javax.servlet.ServletConfig;
29 import javax.servlet.ServletException;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
32
33 import org.eclipse.jetty.client.api.ContentProvider;
34 import org.eclipse.jetty.client.api.Request;
35 import org.eclipse.jetty.client.api.Response;
36 import org.eclipse.jetty.client.api.Result;
37 import org.eclipse.jetty.client.util.InputStreamContentProvider;
38 import org.eclipse.jetty.http.HttpVersion;
39 import org.eclipse.jetty.util.Callback;
40
41
42
43
44
45
46
47
48
49 public class ProxyServlet extends AbstractProxyServlet
50 {
51 @Override
52 protected void service(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException
53 {
54 final int requestId = getRequestId(request);
55
56 URI rewrittenURI = rewriteURI(request);
57
58 if (_log.isDebugEnabled())
59 {
60 StringBuffer uri = request.getRequestURL();
61 if (request.getQueryString() != null)
62 uri.append("?").append(request.getQueryString());
63 if (_log.isDebugEnabled())
64 _log.debug("{} rewriting: {} -> {}", requestId, uri, rewrittenURI);
65 }
66
67 if (rewrittenURI == null)
68 {
69 onRewriteFailed(request, response);
70 return;
71 }
72
73 final Request proxyRequest = getHttpClient().newRequest(rewrittenURI)
74 .method(request.getMethod())
75 .version(HttpVersion.fromString(request.getProtocol()));
76
77 copyHeaders(request, proxyRequest);
78
79 addProxyHeaders(request, proxyRequest);
80
81 final AsyncContext asyncContext = request.startAsync();
82
83 asyncContext.setTimeout(0);
84 proxyRequest.timeout(getTimeout(), TimeUnit.MILLISECONDS);
85
86 if (hasContent(request))
87 proxyRequest.content(proxyRequestContent(proxyRequest, request));
88
89 customizeProxyRequest(proxyRequest, request);
90
91 sendProxyRequest(request, response, proxyRequest);
92 }
93
94
95
96
97 @Deprecated
98 protected void copyHeaders(HttpServletRequest clientRequest, Request proxyRequest)
99 {
100 copyRequestHeaders(clientRequest, proxyRequest);
101 }
102
103 protected ContentProvider proxyRequestContent(final Request proxyRequest, final HttpServletRequest request) throws IOException
104 {
105 return new ProxyInputStreamContentProvider(proxyRequest, request, request.getInputStream());
106 }
107
108 protected Response.Listener newProxyResponseListener(HttpServletRequest request, HttpServletResponse response)
109 {
110 return new ProxyResponseListener(request, response);
111 }
112
113 protected void onClientRequestFailure(Request proxyRequest, HttpServletRequest request, Throwable failure)
114 {
115 if (_log.isDebugEnabled())
116 _log.debug(getRequestId(request) + " client request failure", failure);
117 proxyRequest.abort(failure);
118 }
119
120
121
122
123 @Deprecated
124 protected void onRewriteFailed(HttpServletRequest request, HttpServletResponse response) throws IOException
125 {
126 onProxyRewriteFailed(request, response);
127 }
128
129
130
131
132 @Deprecated
133 protected void onResponseHeaders(HttpServletRequest request, HttpServletResponse response, Response proxyResponse)
134 {
135 onServerResponseHeaders(request, response, proxyResponse);
136 }
137
138
139 @Override
140 protected String filterServerResponseHeader(HttpServletRequest clientRequest, Response serverResponse, String headerName, String headerValue)
141 {
142 return filterResponseHeader(clientRequest, headerName, headerValue);
143 }
144
145 protected void onResponseContent(HttpServletRequest request, HttpServletResponse response, Response proxyResponse, byte[] buffer, int offset, int length, Callback callback)
146 {
147 try
148 {
149 if (_log.isDebugEnabled())
150 _log.debug("{} proxying content to downstream: {} bytes", getRequestId(request), length);
151 response.getOutputStream().write(buffer, offset, length);
152 callback.succeeded();
153 }
154 catch (Throwable x)
155 {
156 callback.failed(x);
157 }
158 }
159
160
161
162
163 @Deprecated
164 protected void onResponseSuccess(HttpServletRequest request, HttpServletResponse response, Response proxyResponse)
165 {
166 onProxyResponseSuccess(request, response, proxyResponse);
167 }
168
169
170
171
172 @Deprecated
173 protected void onResponseFailure(HttpServletRequest request, HttpServletResponse response, Response proxyResponse, Throwable failure)
174 {
175 onProxyResponseFailure(request, response, proxyResponse, failure);
176 }
177
178
179
180
181 @Deprecated
182 protected URI rewriteURI(HttpServletRequest request)
183 {
184 String newTarget = rewriteTarget(request);
185 return newTarget == null ? null : URI.create(newTarget);
186 }
187
188
189
190
191 @Deprecated
192 protected void customizeProxyRequest(Request proxyRequest, HttpServletRequest request)
193 {
194 }
195
196
197
198
199
200
201
202
203
204
205
206
207 @Deprecated
208 protected String filterResponseHeader(HttpServletRequest request, String headerName, String headerValue)
209 {
210 return headerValue;
211 }
212
213
214
215
216
217
218 public static class Transparent extends ProxyServlet
219 {
220 private final TransparentDelegate delegate = new TransparentDelegate(this);
221
222 @Override
223 public void init(ServletConfig config) throws ServletException
224 {
225 super.init(config);
226 delegate.init(config);
227 }
228
229 @Override
230 protected URI rewriteURI(HttpServletRequest request)
231 {
232 return URI.create(delegate.rewriteTarget(request));
233 }
234 }
235
236 protected class ProxyResponseListener extends Response.Listener.Adapter
237 {
238 private final HttpServletRequest request;
239 private final HttpServletResponse response;
240
241 protected ProxyResponseListener(HttpServletRequest request, HttpServletResponse response)
242 {
243 this.request = request;
244 this.response = response;
245 }
246
247 @Override
248 public void onBegin(Response proxyResponse)
249 {
250 response.setStatus(proxyResponse.getStatus());
251 }
252
253 @Override
254 public void onHeaders(Response proxyResponse)
255 {
256 onResponseHeaders(request, response, proxyResponse);
257 }
258
259 @Override
260 public void onContent(final Response proxyResponse, ByteBuffer content, final Callback callback)
261 {
262 byte[] buffer;
263 int offset;
264 int length = content.remaining();
265 if (content.hasArray())
266 {
267 buffer = content.array();
268 offset = content.arrayOffset();
269 }
270 else
271 {
272 buffer = new byte[length];
273 content.get(buffer);
274 offset = 0;
275 }
276
277 onResponseContent(request, response, proxyResponse, buffer, offset, length, new Callback()
278 {
279 @Override
280 public void succeeded()
281 {
282 callback.succeeded();
283 }
284
285 @Override
286 public void failed(Throwable x)
287 {
288 callback.failed(x);
289 proxyResponse.abort(x);
290 }
291 });
292 }
293
294 @Override
295 public void onComplete(Result result)
296 {
297 if (result.isSucceeded())
298 onResponseSuccess(request, response, result.getResponse());
299 else
300 onResponseFailure(request, response, result.getResponse(), result.getFailure());
301 if (_log.isDebugEnabled())
302 _log.debug("{} proxying complete", getRequestId(request));
303 }
304 }
305
306 protected class ProxyInputStreamContentProvider extends InputStreamContentProvider
307 {
308 private final Request proxyRequest;
309 private final HttpServletRequest request;
310
311 protected ProxyInputStreamContentProvider(Request proxyRequest, HttpServletRequest request, InputStream input)
312 {
313 super(input);
314 this.proxyRequest = proxyRequest;
315 this.request = request;
316 }
317
318 @Override
319 public long getLength()
320 {
321 return request.getContentLength();
322 }
323
324 @Override
325 protected ByteBuffer onRead(byte[] buffer, int offset, int length)
326 {
327 if (_log.isDebugEnabled())
328 _log.debug("{} proxying content to upstream: {} bytes", getRequestId(request), length);
329 return onRequestContent(proxyRequest, request, buffer, offset, length);
330 }
331
332 protected ByteBuffer onRequestContent(Request proxyRequest, final HttpServletRequest request, byte[] buffer, int offset, int length)
333 {
334 return super.onRead(buffer, offset, length);
335 }
336
337 @Override
338 protected void onReadFailure(Throwable failure)
339 {
340 onClientRequestFailure(proxyRequest, request, failure);
341 }
342 }
343 }