Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@

import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.RuntimeExchangeException;
import org.apache.camel.converter.stream.CachedOutputStream;
import org.apache.camel.support.CamelObjectInputStream;
import org.apache.camel.support.DeserializationFilterHelper;
Expand Down Expand Up @@ -211,12 +210,9 @@ public static String createURL(Exchange exchange, HttpCommonEndpoint endpoint) {
uri = endpoint.getHttpUri().toASCIIString();
}

// resolve placeholders in uri
try {
uri = exchange.getContext().resolvePropertyPlaceholders(uri);
} catch (Exception e) {
throw new RuntimeExchangeException("Cannot resolve property placeholders with uri: " + uri, exchange, e);
}
// NOTE: no placeholder resolution here. When uri came from the endpoint it was already resolved at
// build time, and when it came from the CamelHttpUri header it carries message content
// (see CAMEL-24282 / CAMEL-24418)

// append HTTP_PATH to HTTP_URI if it is provided in the header
String path = exchange.getIn().getHeader(Exchange.HTTP_PATH, String.class);
Expand Down Expand Up @@ -331,12 +327,8 @@ public static HttpMethods createMethod(Exchange exchange, HttpCommonEndpoint end
String queryString = exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class);
// We need also check the HTTP_URI header query part
String uriString = exchange.getIn().getHeader(Exchange.HTTP_URI, String.class);
// resolve placeholders in uriString
try {
uriString = exchange.getContext().resolvePropertyPlaceholders(uriString);
} catch (Exception e) {
throw new RuntimeExchangeException("Cannot resolve property placeholders with uri: " + uriString, exchange, e);
}
// NOTE: property placeholders are resolved at build time on the endpoint uri written in the route,
// never on this header value, which carries message content (see CAMEL-24282 / CAMEL-24418)
if (uriString != null) {
// in case the URI string contains unsafe characters
uriString = UnsafeUriCharactersEncoder.encodeHttpURI(uriString);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import java.net.URISyntaxException;

import org.apache.camel.Exchange;
import org.apache.camel.RuntimeExchangeException;
import org.apache.camel.StreamCache;
import org.apache.camel.component.http.HttpConstants;
import org.apache.camel.component.http.HttpEndpoint;
Expand All @@ -46,12 +45,8 @@ public static HttpMethods createMethod(Exchange exchange, HttpEndpoint endpoint)
uriString = exchange.getIn().getHeader(HttpConstants.HTTP_URI, String.class);
}
if (uriString != null) {
// resolve placeholders in uriString
try {
uriString = exchange.getContext().resolvePropertyPlaceholders(uriString);
} catch (Exception e) {
throw new RuntimeExchangeException("Cannot resolve property placeholders with uri: " + uriString, exchange, e);
}
// NOTE: property placeholders are resolved at build time on the endpoint uri written in the route,
// never on this header value, which carries message content (see CAMEL-24282 / CAMEL-24418)
// in case the URI string contains unsafe characters
uriString = UnsafeUriCharactersEncoder.encodeHttpURI(uriString);
URI uri = new URI(uriString);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.http;

import java.util.Properties;

import org.apache.camel.Exchange;
import org.apache.camel.http.common.HttpHelper;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.support.DefaultExchange;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

/**
* Property placeholders are resolved at build time on the endpoint uri written in the route, never on the
* {@code CamelHttpUri} header, which carries message content. See CAMEL-24282 / CAMEL-24418.
*/
class HttpUriHeaderPlaceholderTest {

@Test
void placeholderInHttpUriHeaderIsNotResolved() throws Exception {
try (DefaultCamelContext context = new DefaultCamelContext()) {
Properties prop = new Properties();
prop.setProperty("secretValue", "s3cr3t");
context.getPropertiesComponent().setInitialProperties(prop);
context.start();

HttpEndpoint endpoint = context.getEndpoint("http://localhost/base", HttpEndpoint.class);
Exchange exchange = new DefaultExchange(context);
exchange.getIn().setHeader(Exchange.HTTP_URI, "http://localhost/api?k={{secretValue}}");

// the token survives as a literal (percent-encoded by UnsafeUriCharactersEncoder, as any other
// unsafe character in a header-supplied uri would be) and is never expanded
assertThat(HttpHelper.createURL(exchange, endpoint))
.isEqualTo("http://localhost/api?k=%7B%7BsecretValue%7D%7D")
.doesNotContain("s3cr3t");
}
}

@Test
void placeholderInEndpointUriIsResolvedAtBuildTime() throws Exception {
try (DefaultCamelContext context = new DefaultCamelContext()) {
Properties prop = new Properties();
prop.setProperty("basePath", "resolved");
context.getPropertiesComponent().setInitialProperties(prop);
context.start();

// control: a placeholder written in the route's endpoint uri is still resolved, as before
HttpEndpoint endpoint = context.getEndpoint("http://localhost/{{basePath}}", HttpEndpoint.class);
Exchange exchange = new DefaultExchange(context);

assertThat(HttpHelper.createURL(exchange, endpoint)).isEqualTo("http://localhost/resolved");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import io.netty.handler.codec.http.HttpMethod;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.RuntimeExchangeException;
import org.apache.camel.support.DeserializationFilterHelper;
import org.apache.camel.util.CollectionHelper;
import org.apache.camel.util.IOHelper;
Expand Down Expand Up @@ -165,12 +164,8 @@ public static String createURL(Exchange exchange, NettyHttpEndpoint endpoint) {
uri = endpoint.getEndpointUri();
}

// resolve placeholders in uri
try {
uri = exchange.getContext().resolvePropertyPlaceholders(uri);
} catch (Exception e) {
throw new RuntimeExchangeException("Cannot resolve property placeholders with uri: " + uri, exchange, e);
}
// NOTE: property placeholders are resolved at build time on the endpoint uri written in the route,
// never on the message-supplied override headers (see CAMEL-24282 / CAMEL-24418)

// append HTTP_PATH to HTTP_URI if it is provided in the header
String path = exchange.getIn().getHeader(NettyHttpConstants.HTTP_PATH, String.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import io.undertow.util.HttpString;
import io.undertow.util.Methods;
import org.apache.camel.Exchange;
import org.apache.camel.RuntimeExchangeException;
import org.apache.camel.util.CollectionHelper;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.URISupport;
Expand Down Expand Up @@ -51,12 +50,8 @@ public static String createURL(Exchange exchange, UndertowEndpoint endpoint) {
uri = endpoint.getHttpURI().toASCIIString();
}

// resolve placeholders in uri
try {
uri = exchange.getContext().resolvePropertyPlaceholders(uri);
} catch (Exception e) {
throw new RuntimeExchangeException("Cannot resolve property placeholders with uri: " + uri, exchange, e);
}
// NOTE: property placeholders are resolved at build time on the endpoint uri written in the route,
// never on the message-supplied override headers (see CAMEL-24282 / CAMEL-24418)

// append HTTP_PATH to HTTP_URI if it is provided in the header
String path = exchange.getIn().getHeader(UndertowConstants.HTTP_PATH, String.class);
Expand Down Expand Up @@ -126,12 +121,8 @@ public static HttpString createMethod(Exchange exchange, UndertowEndpoint endpoi
String queryString = exchange.getIn().getHeader(UndertowConstants.HTTP_QUERY, String.class);
// We need also check the HTTP_URI header query part
String uriString = exchange.getIn().getHeader(UndertowConstants.HTTP_URI, String.class);
// resolve placeholders in uriString
try {
uriString = exchange.getContext().resolvePropertyPlaceholders(uriString);
} catch (Exception e) {
throw new RuntimeExchangeException("Cannot resolve property placeholders with uri: " + uriString, exchange, e);
}
// NOTE: property placeholders are resolved at build time on the endpoint uri written in the route,
// never on this header value, which carries message content (see CAMEL-24282 / CAMEL-24418)
if (uriString != null) {
URI uri = new URI(uriString);
queryString = uri.getQuery();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ public static URI resolveHttpURI(Exchange exchange, VertxHttpEndpoint endpoint)
uri = endpoint.getConfiguration().getHttpUri().toASCIIString();
}

// Resolve property placeholders that may be present in the URI
uri = exchange.getContext().resolvePropertyPlaceholders(uri);
// NOTE: property placeholders are resolved at build time on the endpoint uri written in the route,
// never on the message-supplied override headers (see CAMEL-24282 / CAMEL-24418)

// Append HTTP_PATH header value if is present
String path = message.getHeader(VertxHttpConstants.HTTP_PATH, String.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,37 @@ Applications that aggregate classes outside the default whitelist through the re
without supplying their own `hazelcastInstance` must now provide a `Config` with a
`JavaSerializationFilterConfig` covering their class names.

=== camel-http, camel-http-common, camel-netty-http, camel-undertow, camel-vertx-http - property placeholders in HTTP URI override headers

The HTTP producers no longer resolve property placeholders (`{{...}}`) in the message-supplied
endpoint-URI override headers `CamelHttpUri` and `CamelRestHttpUri`. Those headers carry message
content, while property placeholders are a route and configuration authoring feature resolved at
build time on the endpoint URI written in the route. This is the same alignment 4.22 applied to
`toD` and `enrich`.

Placeholders written in the route's endpoint URI continue to be resolved exactly as before:

[source,java]
----
.to("http://localhost/{{basePath}}")
.to("netty-http:http://localhost/{{basePath}}")
----

A `{{...}}` token arriving in `CamelHttpUri` or `CamelRestHttpUri` is now treated as a literal part
of the URI rather than being expanded. Routes that relied on that expansion must resolve the value
before it reaches the header, or keep the placeholder in the route.

The affected sites, all of which resolved a header-derived or endpoint-derived value per message:

* `camel-http` - `HttpMethodHelper.createMethod`
* `camel-http-common` - `HttpHelper.createURL`, `HttpHelper.createMethod`
* `camel-netty-http` - `NettyHttpHelper.createURL`
* `camel-undertow` - `UndertowHelper.createURL`, `UndertowHelper.createMethod`
* `camel-vertx-http` - `VertxHttpHelper.resolveHttpURI`

Where the value came from the endpoint rather than a header it was already resolved at build time,
so removing the per-message resolution does not change those routes.

=== camel-mail

`MimeMultipartDataFormat` now uses `MailHeaderFilterStrategy` instead of a plain
Expand Down
Loading