Use carefully-typed states/transitions.

Also simplify the body reading protocol, removing the end message.
Call your end action when Body.read returns instead.