I have a type implementing the http.Handler interface where, in its ServeHTTP method, incoming HTTP requests are inspected, some action is taken, a
I used a different approach to this more recently. There is a GetBody method available, through which you can get a new copy of the request body, so instead of doing:
doStuff(r.Body)
You could instead do:
body, _ := r.GetBody()
doStuff(body)
// r.Body is unmodified
This allows you to inspect the request body while still having it around to do further processing later
Try reading into a buffer and then using the buffer to back two new readers, one for you to use, and one for subsequent consumers to use. For example, imagine that we want to modify the following code:
doStuff(r.Body) // r is an http.Request
We could do:
buf, _ := ioutil.ReadAll(r.Body)
rdr1 := ioutil.NopCloser(bytes.NewBuffer(buf))
rdr2 := ioutil.NopCloser(bytes.NewBuffer(buf))
doStuff(rdr1)
r.Body = rdr2 // OK since rdr2 implements the io.ReadCloser interface
// Now the program can continue oblivious to the fact that
// r.Body was ever touched.
Note that *bytes.Buffer does not have a Close() error method, so it doesn't implement the io.ReadCloser interface. Thus, we have to wrap our *bytes.Buffer values in calls to ioutil.NopCloser.