How to get content from a url in Go
Created
Modified
Fetching a URL
Go provides a collection of packages, grouped under net, that make it easy to send and receive information through the Internet. Package http provides HTTP client and server implementations.
package main
import (
"io/ioutil"
"net/http"
)
func main() {
url := "https://go.dev/"
resp, err := http.Get(url)
if err != nil {
// panic
}
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
// upload image
resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
// post form
resp, err := http.PostForm("http://example.com/form", url.Values{"key": {"Value"}, "id": {"123"}})
}
The client must close the response body when finished with it.
For control over HTTP client headers
client := &http.Client{
CheckRedirect: redirectPolicyFunc,
}
resp, err := client.Get("http://example.com")
// ...
req, err := http.NewRequest("GET", "http://example.com", nil)
// ...
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
// ...
// For control over proxies ...
tr := &http.Transport{
MaxIdleConns: 10,
IdleConnTimeout: 30 * time.Second,
DisableCompression: true,
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://example.com")
Fetching URLs Concurrently
One of the most interesting and novel aspects of Go is its support for concurrent program- ming.
package main
import (
"fmt"
"io"
"io/ioutil"
"net/http"
"time"
)
func fetch(url string, ch chan<- string) {
start := time.Now()
resp, err := http.Get(url)
if err != nil {
ch <- fmt.Sprint(err) // send to channel ch
return
}
defer resp.Body.Close()
nbytes, err := io.Copy(ioutil.Discard, resp.Body)
if err != nil {
ch <- fmt.Sprintf("while reading %s: %v", url, err)
return
}
secs := time.Since(start).Seconds()
ch <- fmt.Sprintf("%.2fs %7d %s", secs, nbytes, url)
}
func main() {
urls := []string{"https://go.dev/", "https://www.google.com/"}
ch := make(chan string)
for _, url := range urls {
go fetch(url, ch)
}
for range urls {
fmt.Println(<-ch) // receive from channel ch
}
}
0.95s 15227 https://www.google.com/ 1.13s 58557 https://go.dev/
Questions
How to read gzipped data from http response in Golang?
Golang by default will automatically decode the body of gzipped response. If the Transport requests gzip on its own and gets a gzipped response, it's transparently decoded in the Response.Body. However, if the user explicitly requested gzip it is not automatically uncompressed.