h2non / gock

HTTP traffic mocking and testing made easy in Go ༼ʘ̚ل͜ʘ̚༽
https://pkg.go.dev/github.com/h2non/gock
MIT License
2.09k stars 107 forks source link

Panic after setting BodyBuffer for GET request #73

Open frncmx opened 4 years ago

frncmx commented 4 years ago

I'm new to gock and I'm fiddling with it to get some hands-on experience. This is when I got a panic and 1st it wasn't trivial what's going on. As I understand it now: I got a panic because I set an HTTP body matcher on a GET request. Could we maybe improve the user experience, maybe just by panicking sooner, i.e., when setting the body matcher?

Here is how to reproduce the panic:

package main

import (
    "log"
    "net/http"

    "github.com/h2non/gock"
)

func main() {
    const url = "http://example.com"
    gock.New(url).BodyString("foo")
    if _, err := http.Get(url); err != nil {
        log.Fatal(err)
    }
}

The panic itself:

panic: runtime error: invalid memory address or nil pointer dereference [recovered]
        panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x4d39dd]

goroutine 1 [running]:
io/ioutil.readAll.func1(0xc0001158a8)
        /usr/lib/go/src/io/ioutil/ioutil.go:30 +0x106
panic(0x6c1b20, 0x8edce0)
        /usr/lib/go/src/runtime/panic.go:969 +0x175
bytes.(*Buffer).ReadFrom(0xc000115830, 0x0, 0x0, 0x70f3c0, 0x10, 0x0)
        /usr/lib/go/src/bytes/buffer.go:204 +0x7d
io/ioutil.readAll(0x0, 0x0, 0x200, 0x0, 0x0, 0x0, 0x0, 0x0)
        /usr/lib/go/src/io/ioutil/ioutil.go:36 +0xe5
io/ioutil.ReadAll(...)
        /usr/lib/go/src/io/ioutil/ioutil.go:45
github.com/h2non/gock.MatchBody(0xc00010e000, 0xc00009d5f0, 0x7f52ef684001, 0x0, 0x0)
        /home/frncmx/code/src/github.com/h2non/gock/matchers.go:174 +0x10e
github.com/h2non/gock.(*MockMatcher).Match(0xc0000a82e0, 0xc00010e000, 0xc00009d5f0, 0x108, 0x0, 0xc00004e9e0)
        /home/frncmx/code/src/github.com/h2non/gock/matcher.go:113 +0x77
github.com/h2non/gock.(*Mocker).Match(0xc00009ade0, 0xc00010e000, 0x1, 0x255e2, 0xc00004ea40)
        /home/frncmx/code/src/github.com/h2non/gock/mock.go:113 +0x145
github.com/h2non/gock.MatchMock(0xc00010e000, 0xc00004eaf8, 0x40efb0, 0xc00009ae40, 0x30)
        /home/frncmx/code/src/github.com/h2non/gock/matcher.go:128 +0x7b
github.com/h2non/gock.(*Transport).RoundTrip(0xc0000a8280, 0xc00010e000, 0x0, 0x0, 0x0)
        /home/frncmx/code/src/github.com/h2non/gock/transport.go:59 +0x95
net/http.send(0xc00010e000, 0x767a80, 0xc0000a8280, 0x0, 0x0, 0x0, 0xc0000b6040, 0x203000, 0x1, 0x0)
        /usr/lib/go/src/net/http/client.go:252 +0x453
net/http.(*Client).send(0x8f9940, 0xc00010e000, 0x0, 0x0, 0x0, 0xc0000b6040, 0x0, 0x1, 0xc00010e000)
        /usr/lib/go/src/net/http/client.go:176 +0xff
net/http.(*Client).do(0x8f9940, 0xc00010e000, 0x0, 0x0, 0x0)
        /usr/lib/go/src/net/http/client.go:718 +0x45f
net/http.(*Client).Do(...)
        /usr/lib/go/src/net/http/client.go:586
net/http.(*Client).Get(0x8f9940, 0x710115, 0x12, 0xc0000b2288, 0x3, 0x8)
        /usr/lib/go/src/net/http/client.go:475 +0xbe
net/http.Get(...)
        /usr/lib/go/src/net/http/client.go:447
main.main()
        /home/frncmx/.config/JetBrains/GoLand2020.2/scratches/scratch_7.go:13 +0xbd

I think the root cause might be the same with https://github.com/h2non/gock/issues/70

frncmx commented 4 years ago

Note, the POST version works ofc:

const url = "http://example.com"
gock.New(url).Post("").BodyString("foo")
if _, err := http.Post(url,"text/plain",strings.NewReader("foo")); err != nil {
    log.Fatal(err)
}
h2non commented 4 years ago

The body matcher should be used in pull-only HTTP verbs such as GET or HEAD.

I'm quite busy, but happy to merge a PR.