$Id: 199

$SOId: 1422

Package [net/http](<https://golang.org/pkg/net/http/>) in standard library provides functionality to make HTTP network requests.

In the examples we use httpbin.org which is a clever service that can return specific HTTP responses, which is useful for demonstrating various aspects of HTTP protocol.

Basic HTTP GET

For simplicity this example uses http.Get(). In real programs you should use custom client with a timeout as described below.

// no playground
package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

func main() {
	// :show start
	uri := "<https://httpbin.org/html>"
	resp, err := http.Get(uri)
	if err != nil {
		log.Fatalf("http.Get() failed with '%s'\\n", err)
	}

	// it's important to close resp.Body or else we'll leak network connection
	// it must be done after checking for error because in error case
	// resp.Body can be nil
	defer resp.Body.Close()
	d, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatalf("ioutil.ReadAll() failed with '%s'\\n", err)
	}

	contentType := resp.Header.Get("Content-Type")
	fmt.Printf("http.Get() returned content of type '%s' and size %d bytes.\\nStatus code: %d\\n", contentType, len(d), resp.StatusCode)

	// getting page that doesn't exist return 404
	uri = "<https://httpbin.org/page-doesnt-exist>"
	resp, err = http.Get(uri)
	if err != nil {
		log.Fatalf("http.Get() failed with '%s'\\n", err)
	}

	contentType = resp.Header.Get("Content-Type")
	fmt.Printf("\\nhttp.Get() returned content of type '%s' and size %d bytes.\\nStatus code: %d\\n", contentType, len(d), resp.StatusCode)

	// acessing non-existent host fails
	uri = "<http://website.not-exists.as/index.html>"
	resp, err = http.Get(uri)
	if err != nil {
		fmt.Printf("\\nhttp.Get() failed with: '%s'\\nresp: %v\\n", err, resp)
	}
	// :show end
}

This shows how to make HTTP GET request for a URL (HTML page in this case).

I use uri as variable name because there is net/url package which means using more natural url will lead to naming conflicts when importing net/url in the same file.

When there is no error, http.Get() returns *http.Response with notable fields:

When no error is returned, it’s important to resp.Body.Close() or you will leak resources.

Trying to access page that doesn’t exist on the server returns a response with StatusCode 404 (Not Found).

Trying to access non-existent host will fail, in which case response is nil.

HTTP GET using custom client

http.Get() is just a wrapper that delegates all work http.DefaultClient, which is a package variable of type *http.Client.

It’s best not to use http.Get because default client doesn’t have a timeout, which means it’ll wait forever connecting to slow or buggy or malicious servers.