

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Still calibrating
click for more info
Not enough gems
Cost: 6 gems
1: Headers
incomplete
2: Constraints
incomplete
3: Multiple Values
incomplete
4: Add to Parse
incomplete
5: Live Headers
incomplete
This lesson's interactive features are locked, please to keep using them
All our tests are passing! Now let's hook it up to the state machine and watch it parse the full set of headers.
Back in the request package, we're going to update our (r *Request) parse method to parse the headers in addition to the request line. Let's start with some new tests.
// Test: Standard Headers
reader := &chunkReader{
data: "GET / HTTP/1.1\r\nHost: localhost:42069\r\nUser-Agent: curl/7.81.0\r\nAccept: */*\r\n\r\n",
numBytesPerRead: 3,
}
r, err := RequestFromReader(reader)
require.NoError(t, err)
require.NotNil(t, r)
assert.Equal(t, "localhost:42069", r.Headers["host"])
assert.Equal(t, "curl/7.81.0", r.Headers["user-agent"])
assert.Equal(t, "*/*", r.Headers["accept"])
// Test: Malformed Header
reader = &chunkReader{
data: "GET / HTTP/1.1\r\nHost localhost:42069\r\n\r\n",
numBytesPerRead: 3,
}
r, err = RequestFromReader(reader)
require.Error(t, err)
There's a big change here that can be tricky: parsing the headers may need to happen successfully multiple times, unlike the request line, which we always parse in one go. This is also true of the request body, which we'll cover later. So, because both the headers and the body will need to support multiple "parses" for each "read", I did a little refactor.
I did not change my .parse method signature, but I did move a lot of the functionality to a new method. My .parse now keeps track of the totalBytesParsed, and then starts a loop:
totalBytesParsed := 0
for r.state != requestStateDone {
n, err := r.parseSingle(data[totalBytesParsed:])
// ...
Again, I'm doing this because the header parsing may need to happen multiple times for the same chunk of data because we can have multiple headers in the same chunk. So, I moved the switch/case logic that handles the actual parsing based on the state and moved it into a new nested method called parseSingle.
When you're done parsing all the headers, set the state to requestStateDone and return the total number of bytes parsed, just like before.
Run and submit the CLI tests.