There’s an exercise in the Pragmatic Studio Elixir course in which I need to render a form and post the data back to create some resource.
My API for creating a resource works correctly if I post to it from command line using CURL:
curl -X POST http://localhost:4000/pledges -d 'name=daisy&amount=400'
But whenever I post to it from my form in a browser page, it fails because the request is not correctly parsed. And the reason it can not be correctly parsed is that the data received from the client socket is incomplete.
It’s incomplete because I have installed many plugins in my browser and there are many headers and a very long cookie. I can reproduce the error by using a request that’s long enough:
curl 'http://localhost:4000/pledges' -X POST -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Firefox/102.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Origin: http://localhost:4000' -H 'DNT: 1' -H 'Connection: keep-alive' -H 'Referer: http://localhost:4000/pledges/new' -H 'DFF: 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111123231111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111232311111111111111111111111111111111111111111111111111111111111111111111111111111111111111111232311111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111123231111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112323111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111232311111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111123231111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111' --data-raw 'name=df&amount=32'
But that’s weird, because we are using the following setup when listening:
:gen_tcp.listen(port, [:binary, packet: :raw, active: false, reuseaddr: true])
And length is set to 0 when calling recv
: :gen_tcp.recv(client_socket, 0)
.
According to the document, all available bytes should be returned when the length is 0 and the socket is in raw mode.
When I check the bit size of the truncated request, it’s always 11680 (1460 bytes).