[ 
https://issues.apache.org/jira/browse/CAMEL-9281?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14989608#comment-14989608
 ] 

Edward Welch commented on CAMEL-9281:
-------------------------------------

Was doing some more digging, realized this block of code was changed to address 
[CAMEL-9104] in version 2.16.0, but was not backported to 2.15.x because of 
some refactoring.

Looking at the code in 2.16.0, I have come up with this solution:

{code}
        if (path != null && path.length() > 0) {

            //Find a ? indicating there are query params
            int idx = uri.indexOf("?");

            //Break apart the uri into base and queryParams
            String base;
            String queryParams;
            if (idx == -1) {
                //No query params
                base = uri;
                queryParams = "";
            } else {
                base = uri.substring(0, idx);
                queryParams = uri.substring(idx);
            }

            // if the base ends with a / and the path starts with a /, remove a 
slash from the path
            if (base.endsWith("/") && path.startsWith("/")) {
                path = path.substring(1);
            }
            // if the neither the base ends with a / or the path starts with a 
/, add one to the base
            if (!base.endsWith("/") && !path.startsWith("/") ) {
                base = base + "/";
            }

            // add everything together;
            uri = base.concat(path).concat(queryParams);

        }
{code}

Unfortunately, the patch for this is a little complicated, because the 
HttpHelper tests were not refactored into camel-http-common when HttpHelper was 
moved.  Also, I noticed this code is copied and pasted in the NettyHttpHelper 
class which exists in both the netty and netty4 components.

Not sure the best place to put unit tests for this?

> Http4 component removes trailing slashes from http requests (producer)
> ----------------------------------------------------------------------
>
>                 Key: CAMEL-9281
>                 URL: https://issues.apache.org/jira/browse/CAMEL-9281
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-http, camel-http4
>    Affects Versions: 2.15.4
>            Reporter: Edward Welch
>
> 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:
> {code}
>         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);
>             }
>         }
> {code}
> 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
> {code}
>         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);
>             }
>         }
> {code}
> 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



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to