We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Parsing the Body

We're almost done parsing the request! (Which, frankly, is the hardest part of an HTTP server imo.)

Remember, an HTTP-message has this format:

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

Our current code parses the

  • start-line (request line for requests)
  • field-line (headers)
  • extra CRLF between headers and the body

Let's tackle the [ message-body ]: but beware, it still has an edge case...

According to RFC9110 8.6:

A user agent SHOULD send Content-Length in a request...

And "should" has a specific meaning in RFCs per RFC2119:

This word, or the adjective "RECOMMENDED", mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.

All this to say, for our implementation we're going to assume that if there is no Content-Length header, there is no body present. This is a safe assumption for our purposes, though it might not be true in all cases in the wild.

Assignment

In the request package, update your (r *Request) parse method to parse the body in addition to the request line.

  1. // Test: Standard Body
    reader := &chunkReader{
        data: "POST /submit HTTP/1.1\r\n" +
            "Host: localhost:42069\r\n" +
            "Content-Length: 13\r\n" +
            "\r\n" +
            "hello world!\n",
        numBytesPerRead: 3,
    }
    r, err := RequestFromReader(reader)
    require.NoError(t, err)
    require.NotNil(t, r)
    assert.Equal(t, "hello world!\n", string(r.Body))
    
    // Test: Body shorter than reported content length
    reader = &chunkReader{
        data: "POST /submit HTTP/1.1\r\n" +
            "Host: localhost:42069\r\n" +
            "Content-Length: 20\r\n" +
            "\r\n" +
            "partial content",
        numBytesPerRead: 3,
    }
    r, err = RequestFromReader(reader)
    require.Error(t, err)
    

Run and submit the CLI tests.