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

Http4 component removes trailing slashes from http requests (producer)

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 2.15.4, 2.16.1
    • 2.16.2, 2.17.0
    • camel-http, camel-http4
    • None
    • Unknown

    Description

      I have created a scenario which seems to exploit a bug in the HttpHelper createURL method.

      My use case:

      Using http4 component in an http proxy with bridgeEndpoint true

      Send a request such as http://somesite/contextpath

      Request is forwarded by my proxy to a tomcat server. Tomcat will reply with a 302 and a new Location of http://somesite/contextpath/ as this is a built in behavior of tomcat to redirect the caller to the contextpath INCLUDING the trailing slash

      I have http client configured with httpClient.redirectsEnabled=false
      Therefore the 302 is sent back through my proxy to the caller.

      The caller then makes the call to http://somesite/contextpath/

      This is where the problem occurs, within the createUrl method:

              String path = exchange.getIn().getHeader(Exchange.HTTP_PATH, String.class);
              // NOW the HTTP_PATH is just related path, we don't need to trim it
              if (path != null) {
                  if (path.startsWith("/")) {
                      path = path.substring(1);
                  }
                  if (path.length() > 0) {
                      // make sure that there is exactly one "/" between HTTP_URI and
                      // HTTP_PATH
                      if (!uri.endsWith("/")) {
                          uri = uri + "/";
                      }
                      uri = uri.concat(path);
                  }
              }
      

      When the second request is made with the trailing slash, the string "path" is / (just a single forward slash)

      This hits the first conditional and results in true, which the following substring then removes this slash.

      Now path.length() is not > 0 so the second conditional evaluates false.

      And we end up with a uri returned that no longer has the trailing slash.

      This is sent to Tomcat, Tomcat then promptly returns another 302 and a redirect loop is created.

      I think the intent of this block of code is to combine the uri and path and make sure there isn't a duplicate forward slash?

      So the simplest fix I can suggest would be something like

              String path = exchange.getIn().getHeader(Exchange.HTTP_PATH, String.class);
              // NOW the HTTP_PATH is just related path, we don't need to trim it
              if (path != null && ! path.equals("/")) {
                  if (path.startsWith("/")) {
                      path = path.substring(1);
                  }
                  if (path.length() > 0) {
                      // make sure that there is exactly one "/" between HTTP_URI and
                      // HTTP_PATH
                      if (!uri.endsWith("/")) {
                          uri = uri + "/";
                      }
                      uri = uri.concat(path);
                  }
              }
      

      Where we would just check for this case explicitly with:

      if (path != null && ! path.equals("/")) {

      Thoughts?

      I could probably put together a PR and add some test cases

      Attachments

        Activity

          People

            davsclaus Claus Ibsen
            erwelch Edward Welch
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: