You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Marco Collovati (Jira)" <ji...@apache.org> on 2020/09/17 18:49:00 UTC

[jira] [Created] (CAMEL-15547) Wrong URI with http dsl and query parameters

Marco Collovati created CAMEL-15547:
---------------------------------------

             Summary: Wrong URI with http dsl and query parameters
                 Key: CAMEL-15547
                 URL: https://issues.apache.org/jira/browse/CAMEL-15547
             Project: Camel
          Issue Type: Bug
          Components: camel-endpointdsl
    Affects Versions: 3.5.0, 3.4.3
            Reporter: Marco Collovati


When declaring an http endpoint for an URL with a query string using endpoint dsl the target URL is incorrect due to appended value to the last parameter.


 Consider the following route snippet:
{noformat}
...
.to(http("myhost/mypath?param1=a&param2=b").httpMethod("GET"))
...
{noformat}
 

The endpoint URI computed by *AbstractEndpointBuilder* is: {{myhost/mypath?param1=a&param2=b?httpMethod=GET (spot the double question mark) }}and this leads to a wrong http request to {{[http://myhost/mypath?param1=a&param2=b%3FhttpMethod%3DGET]}}.

If the query string is removed from the URI and provided as *Exchange.HTTP_QUERY* header the final HTTP URL is correct.

 

The same route without endpoint dsl works fine
{noformat}
…
to("http://myhost/mypath?param1=a&param2=b&httpMethod=GET")
…
{noformat}
 

The problem may be in the following code in *AbstractEndpointBuilder.computeUri*, where a query string computed with endpoint parameters
 is added to the target path without checking for the presence of a question mark.
{code:java}
String query = URISupport.createQueryString(params, encode);
answer = new NormalizedUri(targetScheme + "://" + targetPath + "?" + query);

{code}
I don't know if this is the desired behavior and potential query string part of URIs should be provided in other ways (eg as header) or if it is a bug.

 

Here is a test to replicate the problem
{code:java}

    @Override
    protected RoutesBuilder createRouteBuilder() throws Exception {
        return new EndpointRouteBuilder() {
            @Override
            public void configure() throws Exception {

                restConfiguration().port(9999);
                rest().get("path/xyz")
                    .to("log:myLogger?level=INFO&showAll=true")
                    .to("mock:result");
                from(direct("test"))
                    .to(http("localhost:9999/path/xyz?param1=1&param1=2").httpMethod("GET"));
                from(direct("test2"))
                    .to("http://localhost:9999/path/xyz?param1=1&param2=2&httpMethod=GET");
            }
        };
    }

    // Test passes
    @Test
    public void testRoute() throws InterruptedException {
        MockEndpoint mockEndpoint = getMockEndpoint("mock:result");

        mockEndpoint.expectedHeaderReceived("param1", "1");
        mockEndpoint.expectedHeaderReceived("param2", "2");

        template.sendBody("direct:test2", null);
        mockEndpoint.assertIsSatisfied();
    }

    // Test fails with
    // java.lang.AssertionError: mock://result Header with name param1 for message: 0. Expected: <1> but was: <[1, 2%3FhttpMethod%3DGET]>
    // Expected :<1>
    // Actual   :<[1, 2%3FhttpMethod%3DGET]>    
    @Test
    public void testEndpointDslRoute() throws InterruptedException {
        MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
        mockEndpoint.expectedHeaderReceived("param1", "1");
        mockEndpoint.expectedHeaderReceived("param2", "2");

        template.sendBody("direct:test", null);
        mockEndpoint.assertIsSatisfied();
    }


{code}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)