Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Receive Data

Now that you have accepted a connection, you must read the HTTP Request being sent by the client.

HTTP is a text-based protocol. A client request is simply a stream of raw bytes containing ASCII text, formatted according to strict grammar rules defined in the RFCs.

The Anatomy of an HTTP Request

According to RFC 9112 Section 2.1, an HTTP message consists of:

HTTP-message   = start-line
                *( field-line CRLF )
                CRLF
                [ message-body ]

Let’s break down this ABNF (Augmented Backus-Naur Form) syntax:

  • start-line: A single line detailing the request (method, target, version).
  • *( field-line CRLF ): Zero or more field lines (commonly known as headers), each ending with a CRLF. Semantically, these “field lines” carry the metadata of the HTTP message as key-value pairs. While developers usually call them “headers”, the specification formally refers to them as field lines because they are parsed line-by-line before being interpreted as logical fields.
  • CRLF: An empty line signaling the end of the headers.
  • [ message-body ]: An optional body payload.

Important

CRLF stands for Carriage Return (\r) and Line Feed (\n). You must look for \r\n to separate lines, not just \n. The end of the header section is explicitly marked by a double CRLF sequence (\r\n\r\n).

Your Task

The tester will connect to your server and slowly stream an HTTP request in multiple chunks.

You must read data from the connection until you encounter the \r\n\r\n sequence, which tells you that the HTTP headers are finished.

For this stage, you don’t need to send a valid HTTP response back yet. However, your server must not close the connection until it has fully received the \r\n\r\n boundary.

Warning: If your server uses a blocking read without checking for the \r\n\r\n boundary, it might hang indefinitely waiting for more data!


Important

Run the below docker command to test your solution.

docker run \
  --rm \
  --add-host host.docker.internal:host-gateway \
  codeberg.org/level0/buildit/http-server:latest \
  --addr host.docker.internal:8080 \
  --until receive_data