telefonicaid / fiware-orion

Context Broker and CEF building block for context data management, providing NGSI interfaces.
https://fiware-orion.rtfd.io/
GNU Affero General Public License v3.0
212 stars 264 forks source link

Chunked requests support (avoiding "Zero/No Content-Length in PUT/POST/PATCH request" error on some POST requests) #4273

Open Cerfoglg opened 1 year ago

Cerfoglg commented 1 year ago

Bug description We noticed an erroneous behaviour when attempting to create a new entity via a POST request on /v2/entities. We are setting up an application that uses Envoy and its External Processor library to intercept a POST made to Orion, alter the body of the request, and send the new body to Orion. However, upon doing this Orion will return the error reported in the title above, despite the Content-Length header being present, and the body still present. Even without altering the body, merely copying it, it causes this error to occur, when otherwise the body is accepted by Orion when sent directly.

The work in progress of what we are doing: https://github.com/orchestracities/amon/tree/using-anonympy Specifically: https://github.com/orchestracities/amon/tree/using-anonympy/envoy_ext_proc

We believe this issue might be similar to what was reported here: https://stackoverflow.com/questions/55335716/error-when-im-trying-to-do-a-post-request-in-fiware

How to reproduce it Running this Docker-Compose: https://github.com/orchestracities/amon/blob/using-anonympy/docker-compose.yaml

When attempting to post to Orion through the Envoy proxy (port 8000 by default) the error occurs.

Expected behavior Orion should accept a basic entity creation without that error.

Additional information ...

fgalan commented 1 year ago

Running this Docker-Compose: https://github.com/orchestracities/amon/blob/using-anonympy/docker-compose.yaml

Trying to access that link I get a 404 error. Maybe the file is in a private repository?

Cerfoglg commented 1 year ago

You're right, sorry about that. I invited you to get read access there so you can have a look at what the setup is.

fgalan commented 1 year ago

You should change:

image: fiware/orion-ld:${ORION_VERSION:-1.1.1}

to

image: telefonicaiot/fiware-orion:3.8.0

Orion 3.8.0 (and not Orion-LD 1.1.1) should be the one to use if you are working with NGSIv2 (as POST /v2/entities is).

Please do that and tell us how it goes.

Cerfoglg commented 1 year ago

No luck, same error remains. From the Orion logs I see the POST body I was testing with, but it still insists about the lack of length header, when I already confirmed it's there:

amon-upstream-service-1 | time=2023-02-09T08:39:48.260Z | lvl=INFO | corr=4fc8da5c-a855-11ed-8020-0242c0a81005 | trans=1675931839-739-00000000005 | from=192.168.16.4 | srv=tenant1 | subsrv=/ | comp=Orion | op=logTracing.cpp[148]:logInfoRequestWithPayload | msg=Request received: POST /v2/entities, request payload (158 bytes): { amon-upstream-service-1 | "id": "Person1", amon-upstream-service-1 | "type": "Person", amon-upstream-service-1 | "name": { amon-upstream-service-1 | "value": "Giacomo", amon-upstream-service-1 | "type": "String" amon-upstream-service-1 | }, amon-upstream-service-1 | "age": { amon-upstream-service-1 | "value": 20, amon-upstream-service-1 | "type": "Integer" amon-upstream-service-1 | } amon-upstream-service-1 | }, response code: 411

fgalan commented 1 year ago

When attempting to post to Orion through the Envoy proxy (port 8000 by default) the error occurs.

So your setup is like this:

(Client sending POST /v2/op/update) -> (Envoy proxy) -> (Orion Context Broker)

Is my understanding correct?

Cerfoglg commented 1 year ago

Correct. The example above was to the /V2/entities endpoint however.

On Thu, 9 Feb 2023, 23:19 Fermín Galán Márquez, @.***> wrote:

When attempting to post to Orion through the Envoy proxy (port 8000 by default) the error occurs.

So your setup is like this:

(Client sending POST /v2/op/update) -> (Envoy proxy) -> (Orion Context Broker)

Is my understanding correct?

— Reply to this email directly, view it on GitHub https://github.com/telefonicaid/fiware-orion/issues/4273#issuecomment-1424911774, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACDJHXQHAYY5G53IVBZFPGTWWVUNRANCNFSM6AAAAAAUNWSYU4 . You are receiving this because you authored the thread.Message ID: @.***>

fgalan commented 1 year ago

... but it still insists about the lack of length header, when I already confirmed it's there

At which point do you confirm that? At "(Client sending POST /v2/op/update) -> (Envoy proxy)" point or at "(Envoy proxy) -> (Orion Context Broker)"?

In any case, I'd suggest to test this scenario:

(Client sending POST /v2/op/update) -> (Orion Context Broker)

just to check if Envoy proxy is "eating" the header in some way.

Cerfoglg commented 1 year ago

I've tried the same exact POST request directly to Orion and it worked. I've also tried to sent it through the proxy without altering the body of the request and it also worked. But the moment I try to do any work on the body inside the proxy (so before it is passed to Orion), even if I do nothing to the body (literally copy it as is), that's when Orion tells me the header is missing. This is why I'm guessing that it's not actually a header issue, but something about how the body is being received by Orion that causes issues. This is why I referred to this as well https://stackoverflow.com/questions/55335716/error-when-im-trying-to-do-a-post-request-in-fiware , since it's rather similar.

fgalan commented 1 year ago

I've tried the same exact POST request directly to Orion and it worked

Taking account this I'd say that it is not an issue in Orion. It seems to be an issue in your proxy or its configuration.

From my point of view, this issue could be closed at Orion repository.

Cerfoglg commented 1 year ago

Okay so, after re-checking the setup I found out the problem: the content length header is indeed missing when the request arrives to orion, because upon processing the body the request switches to chunked transfer encoding, thus removing the length header automatically.

So yes, this is issue could be technically closed. But just one question then: is Orion capable of handling a chunked request like this? Or it needs to be in full with Content Length specified always?

fgalan commented 1 year ago

So yes, this is issue could be technically closed. But just one question then: is Orion capable of handling a chunked request like this? Or it needs to be in full with Content Length specified always?

Orion relies on libmicrohttpd as HTTP server library. So I guess that if that library support chunked requests (and it is pretty comprehensive, so probably it does) then Orion should support it.

Cerfoglg commented 1 year ago

Orion atm requires a Content-Lenght Header, so it can't really handle chunked requests if it enforces that. Perhaps it might be worth allowing, maybe through some configuration?

fgalan commented 1 year ago

Orion atm requires a Content-Lenght Header, so it can't really handle chunked requests if it enforces that. Perhaps it might be worth allowing, maybe through some configuration?

In order to support this use case the following should be done:

  1. Check libmicrohttpd chunked requests support and how it is (maybe there are some examples in libmicrohttpd literature)
  2. Review the part of the code in ContextBroker dealing with libmicrohttpd. Have a look specially to high level internal architecture document and this diagram
  3. Change the ContextBroker code (in a pull request)

We would be more than happy to see contributions in this line, providing some degree of (best effort) support solving doubts, etc. and review the pull request with the change. @Cerfoglg maybe do you want to volunteer to do it (it seems you have a use case needing it), please? ;)

fgalan commented 1 year ago

(I have changes the issue title and labels to be more precise)