Agree that removeHeader inbetween the routes fixes the problem.  It's
great experience having to go through all the code to figure out a
content-length header mismatch is the issue since the request just
hangs.  I ran into it again with the following scenerio using the
automatic json binding in the REST DSL with stream caching enabled.

this.getContext().setStreamCaching(true);

restConfiguration().component("netty4-http").port(8282).bindingMode(RestBindingMode.json);
               
                rest("/bind").post()
                    .type(InputDTO.class)
                    .outType(OutputDTO.class)
                    .to("direct:bind");

              from("direct:bind")
                    .setHeader(Exchange.HTTP_METHOD, constant("POST"))
                    .setHeader("Accept", constant("application/json"))
                    .setHeader(Exchange.HTTP_PATH, constant(""))
                    .setHeader(Exchange.CONTENT_TYPE,
constant("application/json"))
                     .process(new Processor() {
                       
                        public void process(Exchange exchange) throws
Exception {
                           InputDTO body =
exchange.getIn().getBody(InputDTO.class);
                           body.setDescription("SomethingElse");
                           
                        }
                    })
                    .marshal().json(JsonLibrary.Jackson)
                    .to("http4://localhost/realservice?bridgeEndpoint=true")
                    .unmarshal().json(JsonLibrary.Jackson,
FinalOutputDTO.class);

The json coming into /bind is pretty printed so includes spaces and
returns.  After it's marshaled to an object and the object is modified
the Content-length will change.  Seems like removing the content-length
header in the DataFormat used to do the marshal ling or perhaps
providing an option in the HTTP Client to ignore the content-header
would be useful.  Again willing to help collaborate on a patch but I'd
like some input on where it would fit best.  Currently thinking either
in the DataFormat marshal methods and/or the HttpProducer.

- Bob

On 2017/09/20 13:13:06, Claus Ibsen <c...@gmail.com> wrote:
> You can remove the header before calling the http endpoints, with>
> removeHeader(Exchange.CONTENT_LENGTH)>
>
> On Sat, Sep 16, 2017 at 9:03 PM, Bob Paulin <bo...@bobpaulin.com> wrote:>
> > Hi,>
> >>
> > I have a camel rest route like the following>
> >>
> > rest("/api/test")>
> > .post()>
> > .to("direct:test");>
> >>
> > from("direct:test").>
> >>
> >
.toD("http4://localhost/test?bridgeEndpoint=true&throwExceptionOnFailure=false")>

> >>
> >
.toD("http4://localhost/test2?bridgeEndpoint=true&throwExceptionOnFailure=false");>

> >>
> >>
> > Trouble occurs when the http4://localhost/test route sets a>
> > content-length header it gets used for http4://localhost/test2. There>
> > are some web servers that use that header to determine request size>
> > which if it never gets to the needed length will never close and
after a>
> > while timeout. This happens despite content-length being in the>
> > HttpHeaderFilterStrategy list because in the HttpProducer class
there is>
> > code like this. So an input stream will still use the header.>
> >>
> > // fallback as input stream>
> > if (answer == null) {>
> > // force the body as an input stream since this>
> > is the fallback>
> > InputStream is =>
> > in.getMandatoryBody(InputStream.class);>
> > String length =>
> > in.getHeader(Exchange.CONTENT_LENGTH, String.class);>
> > InputStreamEntity entity = null;>
> > if (ObjectHelper.isEmpty(length) ) {>
> > entity = new InputStreamEntity(is, -1);>
> > } else {>
> > entity = new InputStreamEntity(is,>
> > Long.parseLong(length));>
> > }>
> > if (contentType != null) {>
> > entity.setContentType(contentType.toString());>
> > }>
> > answer = entity;>
> > }>
> >>
> > I'm assuming there are cases where I might want to explicitly provide>
> > the content-length to the request entity. But I'd like to be able to>
> > turn it off so it always falls back to -1 (chunked).>
> >>
> > I'm working around the issue by doing this:>
> >>
> > from("direct:test").>
> >>
> >
.toD("http4://localhost/test?bridgeEndpoint=true&throwExceptionOnFailure=false")>

> >>
> > .setHeader("Content-Length", constant(""))>
> >>
> >
.toD("http4://localhost/test2?bridgeEndpoint=true&throwExceptionOnFailure=false");>

> >>
> > But I'd like to suggest creating a more global way to ignore the>
> > Content-Length header:>
> >>
> > // fallback as input stream>
> > if (answer == null) {>
> > // force the body as an input stream since this>
> > is the fallback>
> > InputStream is =>
> > in.getMandatoryBody(InputStream.class);>
> > String length =>
> > in.getHeader(Exchange.CONTENT_LENGTH, String.class);>
> > InputStreamEntity entity = null;>
> > if (ObjectHelper.isEmpty(length) ||>
> > getEndpoint().getComponent().isForceChunkedRequestEntity()) {>
> > entity = new InputStreamEntity(is, -1);>
> > } else {>
> > entity = new InputStreamEntity(is,>
> > Long.parseLong(length));>
> > }>
> > if (contentType != null) {>
> > entity.setContentType(contentType.toString());>
> > }>
> > answer = entity;>
> > }>
> >>
> >>
> > Thoughts on this approach? How are other folks dealing with this?>
> > Happy to work on a contribution/patch but I wanted to discuss before>
> > creating a jira.>
> >>
> >>
> > - Bob>
> >>
>
>
>
> -- >
> Claus Ibsen>
> ----------------->
> http://davsclaus.com @davsclaus>
> Camel in Action 2: https://www.manning.com/ibsen2>
>

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to