Skip to content

Conversation

christiankjaer
Copy link
Contributor

Fixes #6427

Around the repository there are different ways that empty responses are encoded. In some places the content length is set to 0, and in other places like the auth middleware, an empty response is returned with no headers set.

Here is a potential fix where an empty body with content-length: 0 is always set when the status code allows a non-empty response and the header is not already set.

Something similar could probably also be done in the request encoding as well.

@mergify mergify bot added series/0.23 PRs targeting 0.23.x module:ember-core labels Jun 4, 2022
rossabaker
rossabaker previously approved these changes Jun 4, 2022
Copy link
Member

@rossabaker rossabaker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍, but I'd like to hear someone else's thought on my worry below.

@@ -63,8 +64,12 @@ private[ember] object Encoder {
()
}
}
if (!chunked && !appliedContentLength && resp.status.isEntityAllowed) {
stringBuilder.append(chunkedTansferEncodingHeaderRaw).append(CRLF)
if (!appliedContentLength && resp.body == EmptyBody && resp.status.isEntityAllowed) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic here looks correct, but it's observable behavior that's dependent on reference equality of a stream. They're both "correct" HTTP, and this is a better outcome for a common case. I think I'm okay with this, but calling it out.

In main, with the new entity model, we can target the Empty entity and not have this concern.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked at it, and I could not see any nice way to check whether a fs2 stream is empty. Maybe somebody can enlighten me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am still confused why it was broken with an empty body and the chunked encoding.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There really isn't a good way. We can "peek" a stream, but that semantically blocks until the first chunk of the body (if any) is produced, and would delay rendering the headers. In scalaz-stream, we used to be able to introspect the algebra and find a wider class of empty streams, but still not all off them. Effects are, well, effectful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok. Makes sense 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'm okay with this, but calling it out.

Seems fine to me.

Comment on lines +141 to +153
test("respToBytes should encode a no body response correctly with stream") {
val resp = Response[IO](Status.Ok, body = Stream.chunk(Chunk.empty))

val expected =
"""HTTP/1.1 200 OK
|Transfer-Encoding: chunked
|
|0
|
|""".stripMargin

Helpers.encodeResponseRig(resp).assertEquals(expected)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So is this intended behavior? I guess it's the only implementation that makes sense.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't think we can do better than this. And even though it's arguably overspecified, I like the test to alert us to behavior changes.

@rossabaker rossabaker dismissed their stale review June 4, 2022 17:27

Build broke

@rossabaker
Copy link
Member

This will need an import sort. I think ember-core/scalafix --all will do it.

Copy link
Member

@rossabaker rossabaker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 if green

@christiankjaer
Copy link
Contributor Author

christiankjaer commented Jun 4, 2022

Only question is whether to actually have main as the base branch, since I observe the bug only on the 1.0 pre release. Maybe that was a bit stupid of me...

@rossabaker
Copy link
Member

Do those tests pass on this branch without your change? I think only one of them would?

We will want to tweak this on the merge to main, where we can detect empty entities (it's a sum type, so no FS2 introspection is involved).

@christiankjaer
Copy link
Contributor Author

Yes. Only one will pass.

@rossabaker
Copy link
Member

I'd say this is correctly targeted for 0.23 then.

Copy link
Member

@armanbilge armanbilge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!

@@ -63,8 +64,12 @@ private[ember] object Encoder {
()
}
}
if (!chunked && !appliedContentLength && resp.status.isEntityAllowed) {
stringBuilder.append(chunkedTansferEncodingHeaderRaw).append(CRLF)
if (!appliedContentLength && resp.body == EmptyBody && resp.status.isEntityAllowed) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'm okay with this, but calling it out.

Seems fine to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

AuthMiddleware with Ember backend returning chunked http response
3 participants