in components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java [153:330]
public void process(Exchange exchange) throws Exception {
boolean cookies = !getEndpoint().getComponent().isCookieManagementDisabled();
if (cookies && getEndpoint().isClearExpiredCookies() && !getEndpoint().isBridgeEndpoint()) {
// create the cookies before the invocation
getEndpoint().getCookieStore().clearExpired(new Date());
}
// if we bridge endpoint then we need to skip matching headers with the HTTP_QUERY to avoid sending
// duplicated headers to the receiver, so use this skipRequestHeaders as the list of headers to skip
Map<String, Object> skipRequestHeaders = null;
if (getEndpoint().isBridgeEndpoint()) {
exchange.setProperty(Exchange.SKIP_GZIP_ENCODING, Boolean.TRUE);
String queryString = exchange.getIn().getHeader(HttpConstants.HTTP_QUERY, String.class);
if (queryString != null) {
skipRequestHeaders = URISupport.parseQuery(queryString, false, true);
}
}
HttpUriRequest httpRequest = createMethod(exchange);
HttpHost httpHost = createHost(httpRequest);
Message in = exchange.getIn();
String httpProtocolVersion = in.getHeader(HttpConstants.HTTP_PROTOCOL_VERSION, String.class);
if (httpProtocolVersion != null) {
// set the HTTP protocol version
int[] version = HttpHelper.parserHttpVersion(httpProtocolVersion);
httpRequest.setVersion(new HttpVersion(version[0], version[1]));
}
HeaderFilterStrategy strategy = getEndpoint().getHeaderFilterStrategy();
if (!getEndpoint().isSkipRequestHeaders()) {
// propagate headers as HTTP headers
if (strategy != null) {
final TypeConverter tc = exchange.getContext().getTypeConverter();
for (Map.Entry<String, Object> entry : in.getHeaders().entrySet()) {
String key = entry.getKey();
// we should not add headers for the parameters in the uri if we bridge the endpoint
// as then we would duplicate headers on both the endpoint uri, and in HTTP headers as well
if (skipRequestHeaders != null && skipRequestHeaders.containsKey(key)) {
continue;
}
Object headerValue = entry.getValue();
if (headerValue != null) {
if (headerValue instanceof String || headerValue instanceof Integer || headerValue instanceof Long
|| headerValue instanceof Boolean || headerValue instanceof Date) {
// optimise for common types
String value = headerValue.toString();
if (!strategy.applyFilterToCamelHeaders(key, value, exchange)) {
httpRequest.addHeader(key, value);
}
continue;
}
// use an iterator as there can be multiple values. (must not use a delimiter, and allow empty values)
final Iterator<?> it = ObjectHelper.createIterator(headerValue, null, true);
HttpUtil.applyHeader(strategy, exchange, it, tc, key,
(multiValues, prev) -> applyHeader(httpRequest, key, multiValues, prev));
}
}
}
}
if (getEndpoint().getCookieHandler() != null) {
Map<String, List<String>> cookieHeaders
= getEndpoint().getCookieHandler().loadCookies(exchange, httpRequest.getUri());
for (Map.Entry<String, List<String>> entry : cookieHeaders.entrySet()) {
String key = entry.getKey();
if (!entry.getValue().isEmpty()) {
// join multi-values separated by semi-colon
httpRequest.addHeader(key, String.join(";", entry.getValue()));
}
}
}
if (getEndpoint().getCustomHostHeader() != null) {
httpRequest.setHeader(HttpConstants.HTTP_HEADER_HOST, getEndpoint().getCustomHostHeader());
}
//In reverse proxy applications it can be desirable for the downstream service to see the original Host header
//if this option is set, and the exchange Host header is not null, we will set it's current value on the httpRequest
if (getEndpoint().isPreserveHostHeader()) {
String hostHeader = exchange.getIn().getHeader(HttpConstants.HTTP_HEADER_HOST, String.class);
if (hostHeader != null) {
//HttpClient 4 will check to see if the Host header is present, and use it if it is, see org.apache.http.protocol.RequestTargetHost in httpcore
httpRequest.setHeader(HttpConstants.HTTP_HEADER_HOST, hostHeader);
}
}
if (getEndpoint().isConnectionClose()) {
httpRequest.addHeader("Connection", HeaderElements.CLOSE);
}
// lets store the result in the output message.
try {
executeMethod(exchange,
httpHost, httpRequest,
httpResponse -> {
try {
if (LOG.isDebugEnabled()) {
LOG.debug("Executing http {} method: {}", httpRequest.getMethod(), httpRequest.getUri());
}
int responseCode = httpResponse.getCode();
if (LOG.isDebugEnabled()) {
LOG.debug("Http responseCode: {}", responseCode);
}
if (!throwException) {
// if we do not use failed exception then populate response for all response codes
HttpProducer.this.populateResponse(exchange, httpRequest, httpResponse, strategy, responseCode);
} else {
boolean ok;
if (minOkRange > 0) {
ok = responseCode >= minOkRange && responseCode <= maxOkRange;
} else {
ok = HttpHelper.isStatusCodeOk(responseCode,
HttpProducer.this.getEndpoint().getOkStatusCodeRange());
}
if (ok) {
// only populate response for OK response
HttpProducer.this.populateResponse(exchange, httpRequest, httpResponse, strategy,
responseCode);
} else {
// operation failed so populate exception to throw
throw HttpProducer.this.populateHttpOperationFailedException(exchange, httpRequest,
httpResponse, responseCode);
}
}
} catch (IOException | HttpException | RuntimeCamelException e) {
throw e;
} catch (Exception e) {
throw new RuntimeCamelException(e);
} finally {
if (httpResponse != null && HttpProducer.this.getEndpoint().isDisableStreamCache()) {
// close the stream at the end of the exchange to ensure it gets eventually closed later
exchange.getExchangeExtension().addOnCompletion(new SynchronizationAdapter() {
@Override
public void onDone(Exchange exchange1) {
try {
EntityUtils.consume(httpResponse.getEntity());
} catch (Exception e) {
// ignore
} finally {
try {
EntityUtils.consume(httpRequest.getEntity());
} catch (Exception e) {
// ignore
}
}
}
});
} else if (httpResponse != null) {
// close the stream now
try {
EntityUtils.consume(httpResponse.getEntity());
} catch (Exception e) {
// ignore
} finally {
try {
EntityUtils.consume(httpRequest.getEntity());
} catch (Exception e) {
// ignore
}
}
}
}
return null;
});
} catch (RuntimeCamelException e) {
if (e.getCause() instanceof Exception ex) {
// Rethrow the embedded exception to simulate the same behavior as with version 4
throw ex;
}
throw e;
}
}