title: Golang H2C Server doesn't write full body. Chrome says: "Server reset stream". Only occurs over http2 connection
body: <p>Most Recent Version of Go (1.153)</p>
  <p>Below is the code for reproducibility. Please try to access <a href="https://easy-dp.ngrok.io" rel="nofollow noreferrer">https://easy-dp.ngrok.io</a> to see the issue.</p>
  <p>Here's what I did:</p>
  <ol>
  <li>Create a Reverse Proxy accessing Gzipped/ Br encoded Content</li>
  <li>Request a publicly available URL, I just grabbed Google Analytics</li>
  <li>Attempt to encode and decode the response via an http2 connection with a proxy.modifyresponse function</li>
  <li>Watch as content is dropped.</li>
  </ol>
  <p>However, this only occurs under the following conditions:</p>
  <ul>
  <li>Under SSL, like with  <a href="https://easy-dp.ngrok.io" rel="nofollow noreferrer">https://easy-dp.ngrok.io</a></li>
  <li>When running a <code>proxy.ModifyResponse</code> function</li>
  <li>Decompressing and re-compressing the body (for example, just reading and rewriting the body to new bytes works)</li>
  </ul>
  <pre class="lang-golang prettyprint-override"><code>package main
  
  import (
      &quot;bytes&quot;
      &quot;compress/gzip&quot;
      &quot;fmt&quot;
      &quot;golang.org/x/net/http2&quot;
      &quot;golang.org/x/net/http2/h2c&quot;
      &quot;io/ioutil&quot;
      &quot;net/http&quot;
      &quot;net/http/httputil&quot;
      &quot;strconv&quot;
      &quot;time&quot;
  )
  
  func ForwardAnalytics(req *http.Request) {
      req.URL.Scheme = &quot;https&quot;
      req.URL.Host = &quot;www.google-analytics.com&quot;
      req.Host = &quot;www.google-analytics.com&quot;
      req.URL.Path = &quot;/analytics.js&quot;
      req.Header.Set(&quot;Accept-Encoding&quot;, &quot;gzip&quot;)
  }
  
  func ModifyAnalytics(r *http.Response) error {
      bytesFromBody, err := ioutil.ReadAll(r.Body)
      defer r.Body.Close()
      if err != nil {
          return nil
      }
      if r.Header.Get(&quot;Content-Encoding&quot;) == &quot;gzip&quot; {
          gzipReader, err := gzip.NewReader(bytes.NewBuffer(bytesFromBody))
          if err != nil {
              return nil
          }
          defer gzipReader.Close()
          readableBytes, err := ioutil.ReadAll(gzipReader)
          var b bytes.Buffer
          gzipWriter, err := gzip.NewWriterLevel(&amp;b, gzip.DefaultCompression)
          if err != nil {
              return nil
          }
          defer gzipWriter.Close()
          writtenLen, err := gzipWriter.Write(readableBytes)
          fmt.Println(&quot;Wrote &quot;, writtenLen)
          if err != nil {
              return nil
          }
          r.ContentLength = int64(len(readableBytes))
          r.Header.Set(&quot;Content-Length&quot;, strconv.FormatInt(int64(len(readableBytes)), 10))
          r.Body = ioutil.NopCloser(&amp;b)
  
          return nil
      } else {
          return nil
      }
  }
  
  
  func handleProxy(w http.ResponseWriter, req *http.Request) {
      proxy := httputil.ReverseProxy{
          Director: ForwardAnalytics
      }
      proxy.ModifyResponse = ModifyAnalytics
      proxy.ServeHTTP(w, req)
  
  }
  
  func main() {
      h2s := &amp;http2.Server{
          IdleTimeout: 20 * time.Second,
      }
      mux := http.NewServeMux()
      mux.HandleFunc( &quot;/&quot;, handleProxy)
      s := &amp;http.Server{
          ReadHeaderTimeout: 20 * time.Second,
          ReadTimeout:       10 * time.Second,
          WriteTimeout:      30 * time.Second,
          Addr:              &quot;localhost:8456&quot;,
          Handler:           h2c.NewHandler(mux, h2s),
      }
      s.ListenAndServe()
  }
  </code></pre>
  <h3>What did you expect to see?</h3>
  <p>I expect to see the ability to open the bytes, modify them, and update the response body on an H2C connection</p>
  <h3>What did you see instead?</h3>
  <p>Two things of note happen:</p>
  <ol>
  <li>Chrome gives a nice little error that expands upon what's going on</li>
  </ol>
  <pre><code>{&quot;params&quot;:{&quot;description&quot;:&quot;Server reset stream.&quot;,&quot;net_error&quot;:&quot;ERR_HTTP2_PROTOCOL_ERROR&quot;,&quot;stream_id&quot;:5},&quot;phase&quot;:0,&quot;source&quot;:{&quot;id&quot;:1493828,&quot;start_time&quot;:&quot;732370299&quot;,&quot;type&quot;:1},&quot;time&quot;:&quot;732375561&quot;,&quot;type&quot;:224},
  </code></pre>
  <ol start="2">
  <li>Under the normal http connection, there's no problem, but under the https connection the script may or may not print out to a certain length. Sometimes it doesn't print at all, sometimes it prints about 30%.</li>
  </ol>
  <p>This is a cross browser issue.</p>