stoplightio / prism

Turn any OpenAPI2/3 and Postman Collection file into an API server with mocking, transformations and validations.
https://stoplight.io/open-source/prism
Apache License 2.0
4.22k stars 344 forks source link

Setting both Content-Type: application/json and Content-Length: 0 returns invalid_json error #1745

Open savy opened 3 years ago

savy commented 3 years ago

Describe the bug

Making requests to Prism with both Content-Type: application/json and Content-Length: 0 headers causes an error to be returned.

To Reproduce

  1. Given the OAS 3 Petstore Expanded example spec
  2. Load it into Prism via Docker -
    docker run --init --rm -p 4010:4010 stoplight/prism:4 mock -h 0.0.0.0 https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore-expanded.yaml
  3. Run the following curl command:
    curl -X DELETE 'http://0.0.0.0:4010/pets/212' \
    --header 'Content-Type: application/json' \
    --header 'Content-Length: 0'
  4. See error:
    {
    "error": {
        "code": "invalid_json",
        "message": "Invalid JSON"
    }
    }

Expected behavior

Receive a 204 No Content response

Additional context

The Prism CLI logs don't show the DELETE request at all.

Given the same OpenApi spec, if I run the same DELETE request with only the Content-Type header, it is successful:

curl -X DELETE 'http://0.0.0.0:4010/pets/212' \
--header 'Content-Type: application/json'

Likewise, if I run with only the Content-Length header, it is also successful:

curl -X DELETE 'http://0.0.0.0:4010/pets/212' \
--header 'Content-Length: 0'

I only get an error when I pass both Content-Type: application/json and Content-Length: 0 headers.

I ran into this issue because the OpenAPI Generator for Java/Jersey2 generates code that sends DELETE requests with both of these headers.

marbemac commented 3 years ago

Hi @savy - isn't a content-type of json on the request (indicating what's expected in the request body) and content-length of 0 incompatible? `` empty string w content length 0 is not valid JSON in the first place.

savy commented 3 years ago

Hi @marbemac, I think that makes sense.

I initially opened this issue to find out if this was intentional behavior or not. It seemed like there might be some inconsistency with how Prism handles this scenario. If I run a similar command with with Content-Type application/xml, for example:

curl -X DELETE 'http://0.0.0.0:4010/pets/212' \
--header 'Content-Type: application/xml' \
--header 'Content-Length: 0'

It looks like Prism accepts the request and processes it since this time there is a log. There is no Prism log if I use content-type json:

[7:55:17 PM] › [HTTP SERVER] delete /pets/212 ℹ  info      Request received
[7:55:17 PM] ›     [NEGOTIATOR] ℹ  info      Request contains an accept header: */*
[7:55:17 PM] ›     [VALIDATOR] ✔  success   The request passed the validation rules. Looking for the best response
[7:55:17 PM] ›     [NEGOTIATOR] ℹ  info      Unable to find content for */*. Sending an empty response.
[7:55:17 PM] ›     [NEGOTIATOR] ✔  success   Responding with the requested status code 204

Is a zero length xml considered valid xml? If not, then should this request fail with an invalid_xml type error?

That led me to wonder whether the OpenAPI SDK should be the one to change and stop sending content-type: application/json + content-length: 0 on a DELETE, or if Prism should be changed so that json behaves like xml in this scenario. What do you think?

Appreciate the work on Prism - I looked at several mock server solutions, and Prism is very well done!

chohmann commented 2 years ago

Most likely will be solved with #1939

daniel-white commented 2 years ago

@savy just checking in. i released prism 4.8 where if the body is explicitly empty with a content-type then it should allow this. can you verify that it works with your use case? thanks!

daniel-white commented 2 years ago

i just ran the prism in the docker as the above example, it still exists in 4.8

rattrayalex commented 2 years ago

We hit this as well.

artb1sh commented 1 year ago

i just ran the prism in the docker as the above example, it still exists in 4.10.5 error Request terminated with error: FetchError: invalid json response body at http://localhost:8080 reason: Unexpected end of JSON input

rattrayalex commented 2 months ago

This keeps coming up; could it be prioritized? I think it should be allowable to send an empty body. (Many actual servers allow this, so the mock server isn't being faithful to the actual server behavior by raising a 400 here).

ilanashapiro commented 2 months ago

For some reason this seems to work for me?

image image

It also works exactly as above when I pull the latest github version and use the compiled Prism binary (i.e. with

cli-binaries/prism-cli mock -h 0.0.0.0 https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore-expanded.yaml

)

ilanashapiro commented 2 months ago

@rattrayalex Is the issue still occurring for you? Still haven't been able to repro on my end since I tried last week. Thanks!

rattrayalex commented 2 months ago

This came up for a customer, not for me personally; if you're having a hard time reproducing, can let it drop.