title: Go json.NewDecoder().Decode() doesn't seem to respect context deadline
body: <p>I have a Golang program with a context deadline set. I am sending an HTTP request, and expected to see a deadline exceeded error when Im reading the body.</p>
  <p>It seems that when I read the response body with <code>ioutil.ReadAll</code> then that read method will get interrupted (?) and return the appropriate error (<code>context.DeadlineExceeded</code>).</p>
  <p>However if I read the response body with <code>json.NewDecoder(resp.Body).Decode</code> then the error returned is nil (instead of <code>context.DeadlineExceeded</code>).  My full code is below.  Is this a bug in <code>json.NewDecoder(resp.Body).Decode</code>?</p>
  <pre><code>package main
  
  import (
      &quot;context&quot;
      &quot;encoding/json&quot;
      &quot;fmt&quot;
      &quot;io/ioutil&quot;
      &quot;net/http&quot;
      &quot;time&quot;
  )
  
  var url string = &quot;http://ip.jsontest.com/&quot;
  
  func main() {
      readDoesntFail()
      readFails()
  }
  
  type IpResponse struct {
      Ip string
  }
  
  func readDoesntFail() {
      ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
  
      req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
      if err != nil {
          panic(err)
      }
      resp, err := http.DefaultClient.Do(req)
      if err != nil {
          panic(err)
      }
  
      ipResponse := new(IpResponse)
      time.Sleep(time.Second * 6)
      fmt.Println(&quot;before reading response body, context error is:&quot;, ctx.Err())
      err = json.NewDecoder(resp.Body).Decode(ipResponse)
      if err != nil {
          panic(err)
      }
      fmt.Println(&quot;Expected panic but there was none&quot;)
  }
  
  func readFails() {
      ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
      req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
      if err != nil {
          panic(err)
      }
      resp, err := http.DefaultClient.Do(req)
      if err != nil {
          panic(err)
      }
  
      time.Sleep(time.Second * 6)
      fmt.Println(&quot;before reading response body, context error is:&quot;, ctx.Err())
      _, err = ioutil.ReadAll(resp.Body)
      if err != nil {
          fmt.Println(&quot;received expected error&quot;, err)
      }
  }
  </code></pre>