Uploaded image for project: 'Camel'
  1. Camel
  2. CAMEL-15547

Wrong URI with http dsl and query parameters

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Minor
    • Resolution: Fixed
    • 3.4.3, 3.5.0
    • 3.4.4, 3.6.0
    • camel-endpointdsl
    • None
    • Unknown

    Description

      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:

      ...
      .to(http("myhost/mypath?param1=a&param2=b").httpMethod("GET"))
      ...
      

       

      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

      …
      to("http://myhost/mypath?param1=a&param2=b&httpMethod=GET")
      …
      

       

      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.

      String query = URISupport.createQueryString(params, encode);
      answer = new NormalizedUri(targetScheme + "://" + targetPath + "?" + query);
      
      

      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

      
          @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();
          }
      
      
      

      Attachments

        Activity

          People

            Unassigned Unassigned
            mcollovati Marco Collovati
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: