title: why `nbytes, err := io.Copy(ioutil.Discard, resp.Body)` always returns 0?
body: <p>I've written a simple program that fetch a list of url to store them inside some files. In this example google and gmail. I always run same command in different software version. Program is stored inside goFetchAll: this is the name of compiled version of the algorithm.</p>
  
  <ul>
  <li>go build</li>
  <li>./goFetchAll <a href="http://www.google.com" rel="nofollow noreferrer">http://www.google.com</a> <a href="http://www.gmail.com" rel="nofollow noreferrer">http://www.gmail.com</a></li>
  </ul>
  
  <blockquote>
  <pre><code>0.23s        0  http://www.google.com
  1.15s        0  http://www.gmail.com
  </code></pre>
  </blockquote>
  
  <p>The second number should be the number of bytes of content. But it is alway 0.</p>
  
  <pre><code>package main
  
  import (
      "fmt"
      "io"
      "io/ioutil"
      "net/http"
      "os"
      "strings"
      "time"
  )
  
  func main() {
      start := time.Now()
  
      ch := make(chan string)
  
      for _, url := range os.Args[1:] {
          go fetch(url, ch)
      }
  
      for range os.Args[1:] {
          fmt.Println(&lt;-ch)
      }
  
      secs := time.Since(start).Seconds()
      fmt.Sprintf("%.2fs elapsed\n", secs)
  }
  
  func fetch(url string, ch chan&lt;- string) {
      start := time.Now()
      resp, err := http.Get(url)
      if err != nil {
          ch &lt;- fmt.Sprint(err)
          return
      }
  
      body, err := ioutil.ReadAll(resp.Body)
      if err != nil {
          ch &lt;- fmt.Sprintf("Cant catch content")
          return
      }
  
      nbytes, err := io.Copy(ioutil.Discard, resp.Body)
      defer resp.Body.Close()
      if err != nil {
          ch &lt;- fmt.Sprintf("while reading %s: %v", url, err)
          return
      }
  
      secs := time.Since(start).Seconds()
      ch &lt;- fmt.Sprintf("%.2fs  %7d  %s", secs, nbytes, url)
  
      // store on file
      filename := string(url)
      filename = strings.Replace(filename, ":", "", -1)
      filename = strings.Replace(filename, "//", "-", -1)
      filename = strings.Replace(filename, "/", "", -1)
      filename = strings.Replace(filename, ".", "-", -1)
      filename = "downloads/" + filename + ".html"
  
      f, err := os.Create(filename)
      f.Write(body)
      defer f.Close()
      if err != nil {
          ch &lt;- fmt.Sprintf("while writing %s: %v", url, err)
          return
      }
  }
  </code></pre>
  
  <p>I've also an older version of same script that actually works:</p>
  
  <blockquote>
  <pre><code>0.25s    10363  http://www.google.com
  0.89s    66576  http://www.gmail.com
  </code></pre>
  </blockquote>
  
  <pre><code>package main
  
  import (
      "fmt"
      "io"
      "io/ioutil"
      "net/http"
      "os"
      "time"
  )
  
  func main() {
      start := time.Now()
  
      ch := make(chan string)
  
      for _, url := range os.Args[1:] {
          go fetch(url, ch)
      }
  
      for range os.Args[1:] {
          fmt.Println(&lt;-ch)
      }
  
      fmt.Println("%.2fs elapsed\n", time.Since(start).Seconds())
  }
  
  func fetch(url string, ch chan&lt;- string) {
      start := time.Now()
      resp, err := http.Get(url)
      if err != nil {
          ch &lt;- fmt.Sprint(err)
          return
      }
  
      nbytes, err := io.Copy(ioutil.Discard, resp.Body)
      resp.Body.Close()
      if err != nil {
          ch &lt;- fmt.Sprintf("whioe reading %s: %v", url, err)
          return
      }
  
      secs := time.Since(start).Seconds()
      ch &lt;- fmt.Sprintf("%.2fs  %7d  %s", secs, nbytes, url)
  }
  </code></pre>
  
  <p>Can someone explain why the newest version always count 0 seconds?</p>
  
  <hr>
  
  <p>My partial solution is the following. I've just request again <code>http.Get(url)</code></p>
  
  <pre><code>resp, err := http.Get(url)
  nbytes, err := io.Copy(ioutil.Discard, resp.Body)
  defer resp.Body.Close() // dont leak resources
  if err != nil {
      ch &lt;- fmt.Sprintf("while reading %s: %v", url, err)
      return
  }
  
  resp, err = http.Get(url)
  body, err := ioutil.ReadAll(resp.Body)
  if err != nil {
      ch &lt;- fmt.Sprintf("Cant catch content")
      return
  }
  </code></pre>