Hopefully nobody expects software to be perfect. However, when a small and fixable issue is taken as an indicative of a bigger problem, when it is not, the lasting impression is that we don’t have a lot of space for making mistakes (exactly because small mistakes will be taken as an indicative of a bigger problem, when they are not, so we need to make sure everything is fail proof).
Reading and writing a body is always impure. You can’t escape from the real world. The question is how and when you handle it. If you choose to not expose it to your users at all, with a completely pure data driven approach of the request and response with no callbacks, then you are removing runtime capabilities from your users in terms of connection and memory management.
A callback based approach can be made of pure callbacks but the model is still impure and some of the callbacks are likely dictated by the impure nature of the model. For example, in a GenServer you still have
GenServer.reply/2, which is an impure operation, because otherwise certain patterns are impossible to implement.
I am not saying one approach is better than the other. My point is that because the domain modelled here is inherently impure, concessions have to be made at some point (in Erlang/Elixir at least).
Attacks like slowloris are easier to pull off when the body is being kept in memory, especially because the body size limit is typically way higher than the headers one.