h2non/gentleman

Using body plugin will destroy the context.

elonzh opened this issue · 2 comments

You wrap the context storage in *http.Request.Body.

When using body plugin, the plugin replace the *http.Request.Body directly.

Here is a example to reproduce the problem.

package main

import (
	"fmt"

	"gopkg.in/h2non/gentleman.v1"
)

func main() {
	req := gentleman.NewRequest()
	req.Method("GET")
	req.URL("http://httpbin.org/headers")
	// Define the URL path at request level
	//req.Path("/headers")
	// Set a new header field
	req.SetHeader("Client", "gentleman")
	req.Context.Set("Foo", "Bar")
	req.BodyString("Body Hell!")
	// Perform the request
	fmt.Println(req.Context.GetAll(), req.Context.Stopped)
	res, err := req.Do()
	fmt.Println(req.Context.GetAll(), req.Context.Stopped)
	fmt.Println(res.Context.GetAll(), res.Context.Stopped)
	if err != nil {
		fmt.Printf("Request error: %s\n", err)
		return
	}
	if !res.Ok {
		fmt.Printf("Invalid server response: %d\n", res.StatusCode)
		return
	}
	// Reads the whole body and returns it as string
	fmt.Printf("Body: %s", res.String())
}

Output:

map[Foo:Bar] false
map[$phase:response] false
map[$phase:response] false
Body: {
  "headers": {
    "Accept-Encoding": "gzip", 
    "Client": "gentleman", 
    "Content-Length": "14", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "gentleman/1.0.2"
  }
}

This is one of the reasons why I want to switch to net.context.

The fix to this issue should be simple, but I need to make a helper function public in context subpackage.

I think I can provide a fix later today. Thanks for reporting.

h2non commented

This should be fixed. For implementation details, see: b306884

The fixes are shipped in gentleman@v1.0.3. You can upgrade it running:

go get -u gopkg.in/h2non/gentleman.v1