public void process()

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;
        }
    }