title: Go equivalent of Python's requests.Session for making many requests with the same basic authentication?
body: <p>Consider this example for making an HTTP request in Go with basic authentication:</p>
  
  <pre><code>package main
  
  import (
      "encoding/base64"
      "fmt"
      "io/ioutil"
      "net/http"
      "net/http/httptest"
      "strings"
  )
  
  var userName = "myUserName"
  var password = "myPassword"
  
  func main() {
      ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
          if !checkAuth(w, r) {
              http.Error(w, "You're not authorized!", http.StatusUnauthorized)
              return
          }
          w.Write([]byte("You're authorized!"))
      }))
      defer ts.Close()
  
      req, err := http.NewRequest("GET", ts.URL, nil)
      check(err)
  
      req.SetBasicAuth(userName, password+"foo")
  
      resp, err := http.DefaultClient.Do(req)
      check(err)
      defer resp.Body.Close()
  
      body, err := ioutil.ReadAll(resp.Body)
      check(err)
  
      fmt.Println(string(body))
  }
  
  // checkAuth checks authentication (cf. https://stackoverflow.com/questions/21936332/idiomatic-way-of-requiring-http-basic-auth-in-go/21937924#21937924)
  func checkAuth(w http.ResponseWriter, r *http.Request) bool {
      s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
      if len(s) != 2 {
          return false
      }
  
      b, err := base64.StdEncoding.DecodeString(s[1])
      if err != nil {
          return false
      }
  
      pair := strings.SplitN(string(b), ":", 2)
      if len(pair) != 2 {
          return false
      }
  
      return pair[0] == userName &amp;&amp; pair[1] == password
  }
  
  func check(err error) {
      if err != nil {
          panic(err)
      }
  }
  </code></pre>
  
  <p>Note that <code>SetBasicAuth</code> is a method of an <code>*http.Request</code>, so if I want to make many requests, I would have to call this method on each request.</p>
  
  <p>In Python, you can define a <code>requests.Session</code> like in this example (from <a href="https://requests.readthedocs.io/en/master/user/advanced/#session-objects" rel="nofollow noreferrer">https://requests.readthedocs.io/en/master/user/advanced/#session-objects</a>):</p>
  
  <pre class="lang-py prettyprint-override"><code>s = requests.Session()
  s.auth = ('user', 'pass')
  s.headers.update({'x-test': 'true'})
  
  # both 'x-test' and 'x-test2' are sent
  s.get('https://httpbin.org/headers', headers={'x-test2': 'true'})
  </code></pre>
  
  <p>Is there an idiomatic way of defining the equivalent of a <code>requests.Session</code> in Go (preferably using the standard library)? All I can think of is defining a custom client struct with its own <code>Do()</code> method:</p>
  
  <pre><code>type MyClient struct {
      UserName, Password string
  }
  
  func (client *MyClient) Do(req *http.Request) (*http.Response, error) {
      req.SetBasicAuth(client.UserName, client.Password)
      return http.DefaultClient.Do(req)
  }
  </code></pre>
  
  <p>and invoking it in the above script like</p>
  
  <pre><code>client := MyClient{UserName: userName, Password: password}
  
  resp, err := client.Do(req)
  </code></pre>
  
  <p>Would this be an idiomatic way to avoid multiple calls to <code>SetBasicAuth()</code>?</p>