"runtime error" when reading from request body in http test

142 views
Skip to first unread message

i...@bodokaiser.io

unread,
Jul 6, 2014, 1:52:49 PM7/6/14
to golan...@googlegroups.com
Hello,

I have problems with a runtime error which occurs when testing my http handles.

I extracted the problematic code and reduced it to this setup:

package main
 
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/http/httptest"
)
 
func main() {
rec := httptest.NewRecorder()
 
req, err := http.NewRequest("POST", "/", nil)
 
if err != nil {
log.Fatal(err)
}
 
req.Write(bytes.NewBufferString("Hello"))
 
Handle(rec, req)
}
 
func Handle(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body)
 
if err != nil {
log.Fatal(err)
}
 
fmt.Printf("Body: %s", body)
}



I read something that this occurs because of concurrent io operations on the request body. However I do not know how to solve this. Any suggestions?

PS: passing the io.Reader directly to NewRequest is not an option as I need to add headers in the original use case.

Bo

i...@bodokaiser.io

unread,
Jul 6, 2014, 2:00:17 PM7/6/14
to golan...@googlegroups.com, i...@bodokaiser.io
Passing the io.Reader directly to NewRequest does work. Strange that this does work as I still can set header after wards.

However what was the problem of the initial setup?

Rui Ueyama

unread,
Jul 6, 2014, 2:33:54 PM7/6/14
to Bodo Kaiser, golang-nuts
Seems like you do not understand what (*Request).Write does. I'm guessing you think that the method would add a given io.Reader to the request as its request body. That's not what that method does.

Write dumps the request to a given io.Writer in the wire format. That's probably totally different from what you assumed. Because Write does not set r.Body, it remains nil, which causes io.ReadAll to panic.

What are you actually trying to achieve?


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Matt Harden

unread,
Jul 6, 2014, 3:33:50 PM7/6/14
to Rui Ueyama, Bodo Kaiser, golang-nuts
This is probably what you want. http://play.golang.org/p/xpChdYyXWH

You are still able to set headers because your Body has not been read yet. When the http.Client sends the request, for example when you call client.Do(req), the client will make a connection, send the request (like "GET /") and the headers, then copies the body of the request from the io.ReadCloser you supplied as req.Body.
Reply all
Reply to author
Forward
0 new messages