It's been a while since I dealt with go and I seem to have forgotten how to read the docs.
If I do a get request like this...
resp, err := http.Get("https://example.com")
I then see that the response has a Body
that is of an io.ReadCloser
type (https://golang.org/pkg/io/#ReadCloser). I see the ReadCloser is an interface to Reader
and Closer
.
When I look at the Reader
interface I see it has a Read
method that reads bytes into p
(https://golang.org/pkg/io/#Reader).
To recap, the http Response
has a body which is a io.ReadCloser
Interface which itself contains a Reader
interface which has a Read
method.
When I try this I would expect to Read
the response bytes into HTML, but I see nothing...
var html []byte
num, err := resp.Body.Read(html)
fmt.Println("\n\thtml: ", html)
fmt.Printf("\n\tnum: %v, err: %v\n", num, err)
Output:
html: []
num: 0, err: <nil>
What am I missing here?
short answer: You are passing a slice html
where its len would be '0' and Read reads up to len(html)
bytes into html
Here is snippet from https://golang.org/pkg/io/#Reader
Read reads up to len(p) bytes into p. It returns the number of bytes read (0 <= n <= len(p)) and any error encountered. Even if Read returns n < len(p), it may use all of p as scratch space during the call. If some data is available but not len(p) bytes, Read conventionally returns what is available instead of waiting for more.
Now what you may do use io
and update the code as
body, err := io.ReadAll(resp.Body)
Code
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
resp, err := http.Get("http://httpbin.org/ip")
if err != nil {
fmt.Println("Error making request", err.Error())
return
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response", err.Error())
return
}
fmt.Println("Response\n", string(body))
}
Here is play link, in go playground HTTP requests won't work it is a security precaution so you may test this in your machine