if (url == null) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
final HttpExchange exchange = new CustomHttpExchange(continuation, response, request);
exchange.setScheme(HttpSchemes.HTTPS.equals(request.getScheme()) ? HttpSchemes.HTTPS_BUFFER : HttpSchemes.HTTP_BUFFER);
exchange.setMethod(request.getMethod());
exchange.setURL(url.toString());
exchange.setVersion(request.getProtocol());
logger.debug("{} {} {}", request.getMethod(), url, request.getProtocol());
// check connection header
String connectionHdr = request.getHeader("Connection");
if (connectionHdr != null) {
connectionHdr = connectionHdr.toLowerCase(Locale.ENGLISH);
if (!connectionHdr.contains("keep-alive") && !connectionHdr.contains("close")) {
connectionHdr = null;
}
}
// force host
if (_hostHeader != null) {
exchange.setRequestHeader("Host", _hostHeader);
}
// copy headers
boolean xForwardedFor = false;
boolean hasContent = false;
long contentLength = -1;
Enumeration<?> enm = request.getHeaderNames();
while (enm.hasMoreElements()) {
// TODO could be better than this!
String hdr = (String) enm.nextElement();
String lhdr = hdr.toLowerCase(Locale.ENGLISH);
if ("transfer-encoding".equals(lhdr)) {
if (request.getHeader("transfer-encoding").contains("chunk")) {
hasContent = true;
}
}
if (_DontProxyHeaders.contains(lhdr)) {
continue;
}
if (connectionHdr != null && connectionHdr.contains(lhdr)) {
continue;
}
if (_hostHeader != null && "host".equals(lhdr)) {
continue;
}
if ("content-type".equals(lhdr)) {
hasContent = true;
} else if ("content-length".equals(lhdr)) {
contentLength = request.getContentLength();
exchange.setRequestHeader(HttpHeaders.CONTENT_LENGTH, Long.toString(contentLength));
if (contentLength > 0) {
hasContent = true;
}
} else if ("x-forwarded-for".equals(lhdr)) {
xForwardedFor = true;
}
Enumeration<?> vals = request.getHeaders(hdr);
while (vals.hasMoreElements()) {
String val = (String) vals.nextElement();
if (val != null) {
logger.debug("{}: {}", hdr, val);
exchange.setRequestHeader(hdr, val);
}
}
}
// Proxy headers
exchange.setRequestHeader("Via", "1.1 (jetty)");
if (!xForwardedFor) {
exchange.addRequestHeader("X-Forwarded-For", request.getRemoteAddr());
exchange.addRequestHeader("X-Forwarded-Proto", request.getScheme());
exchange.addRequestHeader("X-Forwarded-Host", request.getHeader("Host"));
exchange.addRequestHeader("X-Forwarded-Server", request.getLocalName());
}
if (hasContent) {
exchange.setRequestContentSource(in);
}
customizeExchange(exchange, request);
/*
* we need to set the timeout on the continuation to take into
* account the timeout of the HttpClient and the HttpExchange
*/
long ctimeout = (_client.getTimeout() > exchange.getTimeout()) ? _client.getTimeout() : exchange.getTimeout();
// continuation fudge factor of 1000, underlying components
// should fail/expire first from exchange
if (ctimeout == 0) {
continuation.setTimeout(0); // ideally never times out