Closed
Description
When a net/http server receives an "Expect: 100-continue" request and doesn't read from the request body (and thus doesn't emit a "100 Continue" response or receive the body from the client), the server still seems to discard Content-Length bytes from the socket, which will consume some or all of the next request when using persistent connections, messing up the connection state.
package main
import (
"io"
"io/ioutil"
"net/http"
)
func hello(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/readbody" {
ioutil.ReadAll(r.Body)
}
io.WriteString(w, "Hello world!")
}
func main() {
http.HandleFunc("/", hello)
http.ListenAndServe(":9000", nil)
}
redbo@precise-saio:~/$ nc 127.0.0.1 9000
PUT /noreadbody HTTP/1.1
User-Agent: PycURL/7.22.0
Host: 127.0.0.1:9000
Accept: */*
Expect: 100-continue
Content-Length: 10
HTTP/1.1 200 OK
Date: Thu, 02 Jul 2015 23:19:06 GMT
Content-Length: 12
Content-Type: text/plain; charset=utf-8
Hello world!PUT /readbody HTTP/1.1
User-Agent: PycURL/7.22.0
Host: 127.0.0.1:9000
Accept: */*
Expect: 100-continue
Content-Length: 10
HTTP/1.1 400 Bad Request
If I go into net/http and print out the error that leads to the 400, it's: malformed HTTP request "ody HTTP/1.1"
, which is 10 bytes (Content-Length) cut off from the first line of the next request.