Hi, course author here! You're right, this was left out initially to scope down the challenge (it's already quite long with 11 stages). We're planning to add it as a challenge extension, uploading is one of the highly voted challenge extension ideas by the community.
If it were structured in fashion closer along the protocol startup process or how a real client is structured more people might end up with a functional client rather than a "bittorrent leecher".
Up to "peer handshake" most things look fine. From there it rushes towards a half-finished goal and if people stop there you're leaving the internet littered with one-sided examples.
After the handshake you'll need state machines to handle multiple peers, piece-sets to track what you've downloaded, the rarest-first algorithm[0], message processing and so on.
The final result of having a downloaded file falls out of that almost as a side-product at some point.