Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

missing Content-Length Header in POST requests sent with EXPath HTTP Client #4642

Open
line-o opened this issue Dec 7, 2022 · 5 comments
Open
Labels
high prio needs documentation Signals issues or PRs that will require an update to the documentation repo

Comments

@line-o
Copy link
Member

line-o commented Dec 7, 2022

Describe the bug

When sending a request with an XML body via POST

hc:send-request(
    <hc:request href="http://localhost:8080/exist/apps/test/controller.xq"
        method="POST" timeout="300">
        <hc:body media-type="application/xml" method="xml">
          <some>data</data>
        </hc:body>
    </hc:request>
)

The content-type-header is set but content-length is absent.

This leads to request:get-data() to be empty, when such a request is received by any XQuery module in eXist-6.0.1.

In contrast a simple curl request

curl http://localhost:8080/exist/apps/test/ --data "<some>content</some>" -H "Content-Type:application/xml"

does set the necessary header and therefore the body can be read.

Affected version: current stable (eXist-6.0.1)
This is fixed in 6.1.0 because request:get-data() does receive contents even if conent-length is absent

I was able to trace it down to the class org.expath.httpclient.impl.SinglePartRequestBody. In the setHeaders method only the content-type header is set. This is confirmed for XML-like payloads but judging from the source code it applies to any single body regardless of its type.
The source code I checked was decompiled from http-client-java-1.4.1.jar

Expected behavior

To either the content-length header to be set automatically or for users to be able to set it manually.

To Reproduce

  1. create collection /db/apps/test

  2. create resource /db/apps/test/controller.xq

<request method="{request:get-method()}">
    <headers>
    {
        for $h in request:get-header-names()
        return <header name="{$h}">{ request:get-header($h) }</header>
    }
    </headers>
    <body>{ request:get-data() }</body>
</request>
  1. evaluate the code below in exide
hc:send-request(
    <hc:request href="http://localhost:8080/exist/apps/test/controller.xq"
        method="POST" timeout="300">
        <hc:body media-type="application/xml" method="xml">
          <some>data</data>
        </hc:body>
    </hc:request>
)
  1. in the response the body element is empty
  2. call curl http://localhost:8080/exist/apps/test/ --data "<some>content</some>" -H "Content-Type:application/xml"
  3. in the response the body has the expected contents

Context (please always complete the following information):

  • OS: macOS 12.6
  • eXist-db version: 6.0.1
  • Java Version 1.8.0_352 (Zulu-aarch64)

Additional context

  • How is eXist-db installed? built from source
  • Any custom changes in e.g. conf.xml? none
@line-o line-o added bug issue confirmed as bug high prio labels Dec 7, 2022
@line-o line-o changed the title http-client:send-request does not set content-length header in post request empty body on POST requests sent with http-client:send-request Dec 7, 2022
@line-o line-o changed the title empty body on POST requests sent with http-client:send-request empty body on POST requests sent with http-client Dec 7, 2022
@adamretter
Copy link
Contributor

adamretter commented Dec 7, 2022

In HTTP 1.1 the Content-Length: header is not used if Transfer-Encoding: chunked is used. If I recall correctly, then chunked is the default for this. I would suggest you capture the HTTP request headers with tcpdump to verify this.

If you want HTTP 1.0 behaviour instead, you just need to specify that option explicitly on your <hc:request element.

Otherwise, if you believe this is an issue with the EXPath HTTP Client then it should be moved to - https://github.com/expath/expath-http-client-java/issues.

@adamretter adamretter changed the title empty body on POST requests sent with http-client Content-Length Header seems to be missing on POST requests sent with EXPath HTTP Client Dec 7, 2022
@line-o line-o changed the title Content-Length Header seems to be missing on POST requests sent with EXPath HTTP Client missing Content-Length Header in POST requests sent with EXPath HTTP Client Dec 7, 2022
@line-o
Copy link
Member Author

line-o commented Dec 7, 2022

@adamretter What is the non-default value of transfer-encoding that allows to set the content-length header and how does one set this in the example above?

@line-o
Copy link
Member Author

line-o commented Dec 7, 2022

I found some interesting info in here about undocumented attributes that can be set
expath/expath-http-client-java#9

@line-o
Copy link
Member Author

line-o commented Dec 7, 2022

Will retest with chunked="false"

@line-o
Copy link
Member Author

line-o commented Dec 7, 2022

I can confirm that the above works.
The attribute chunked has to be set on the request-element.

xquery version "3.1";

import module namespace hc = "http://expath.org/ns/http-client";

hc:send-request(
    <hc:request href="http://localhost:8080/exist/apps/test/controller.xq"
        method="POST" timeout="300" chunked="false">
        <hc:body media-type="application/xml" method="xml">
            <some>content</some>
        </hc:body>
    </hc:request>
)

@line-o line-o added needs documentation Signals issues or PRs that will require an update to the documentation repo and removed bug issue confirmed as bug labels Dec 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
high prio needs documentation Signals issues or PRs that will require an update to the documentation repo
Projects
None yet
Development

No branches or pull requests

2 participants