smithy4s icon indicating copy to clipboard operation
smithy4s copied to clipboard

Incosistent value of content-length header in case of error response for head request

Open ghostbuster91 opened this issue 1 year ago • 3 comments

Actual behavior

Given following smithy definition:

@http(method: "HEAD", uri: "/cities/{cityId}/weather")
@readonly
operation HeadWeather {
    input := {
        @required
        @httpLabel
        cityId: CityId
    }    
    errors: [MyError]
}
@httpError(404)
@error("client")
structure MyError {
    @httpHeader("x-details")
    @required
    details: String
}

and the endpoint implementation:

def headWeather(cityId: CityId) : IO[Unit] = IO.raiseError(MyError("boom"))

querying server returns:

$ curl --head localhost:8080/cities/123/weather                                                                      12:58:18
HTTP/1.1 404 Not Found
Date: Mon, 05 Feb 2024 12:07:08 GMT
Connection: keep-alive
Content-Type: application/json
x-details: boom
X-Error-Type: MyError
X-Amzn-Errortype: MyError
Content-Length: 2

Expected behavior

Since there is no body and the logic does not override the content-length header, the returned content-length should be 0.

Additional notes

Tested against 0.18.6 and 0.17.18 Full reproduction: https://github.com/ghostbuster91/demos/tree/error-content-length

ghostbuster91 avatar Feb 05 '24 12:02 ghostbuster91

I also wonder if we should get rid of Content-Type in these cases. Surely this has been discussed before, and I remember we're getting null bodies in other responses now, but if the response is empty (as it should for HEAD) I'm pretty sure we shouldn't claim it's JSON.

kubukoz avatar Feb 05 '24 14:02 kubukoz

relevant: https://github.com/disneystreaming/smithy4s/issues/1145

daddykotex avatar Feb 05 '24 16:02 daddykotex

Right, so there's two things in this issue ?

  1. Should the logic that removes body from HEAD server responses should execute in the case of errors ?

I think not. This logic is located here here

  1. Why is the header not respecting the fact that we have an empty body ?

I'm honestly not quite sure why. I think the logic at fault is herehere, because if a Content-Length header was already present before the body was set to empty, the case 0 wouldn't update the value in the http4s response.

What I'm not sure about is what piece of logic would update the Content-Length value in the Smithy4sHttpResponse logic. That's somewhat suspicious.

Anyway, if you could raise a PR and add some unit tests, that'd be great.

Baccata avatar Feb 09 '24 14:02 Baccata