Fix setting content-length: 0 for HEAD responses with compression middleware - #755
Conversation
#753 will fix things properly
|
I don't think I really understand what went wrong here. |
|
I understand that its unclear, honestly it wasn't clear to me either. I've done some more digging and think I understand whats going on now: If you have a router like this: Router::new()
.route("/", get(|| async { "Hello, World!" }))
.layer(CompressionLayer::new().compress_when(SizeAbove::new(0)))run it with hyper and send it
I think the most correct thing is to omit the content-length since if the request is issued again with Phew that was a lot 😅 Hopefully it makes sense. |
|
I see two bugs there:
|
The compression middleware was configured with
Hyper does the right thing afaik. Hyper calls |
|
If you send a HEAD request the response is with no body. Before this patch this response would have With this patch the response to This is unchanged by this patch So
|
content-length for chunked responsescontent-length: 0 for HEAD responses with compression middleware
But |
Can you think of other reasonable middlewares / overall setups that would cause the same issue? |
That's true. I think that's a bug in the implementation. The docs says "above a certain size" so I don't think it's a breaking change to fix.
|
Fixes #747
The bug was that applying a middleware to a method router would cause the response to pass through a
RouteFuturetwice and we'd set thecontent-lengthand strip the response body twice. That happened becauseRouter::layerwrapped things in aRoutethen calledMethodRoute::routewhich also applied aRoute.Solved it by having
RouteFuture::pollset a response extension and not alter the response if that is present. Its a little unfortunate to add more overhead here but couldn't think of another solution sinceRouterandMethodRouterneed to be correct and make sense on their own, and needs to support general services that might not handleHEADrequests correctly.I also removed
RouterFuturesoRouter's response is nowRouteFuture<RequestBody, Infallible>. The additional indirection ofRouterFuturehasn't proven to be useful so I think its safe to remove.