code: func (d *DebugUpgrader) Upgrade(conn io.ReadWriter) (hs ws.Handshake, err error) {
  	var (
  		// Take the Reader and Writer partst from conn to be probably replaced
  		// below.
  		r io.Reader = conn
  		w io.Writer = conn
  	)
  	if onRequest := d.OnRequest; onRequest != nil {
  		var buf bytes.Buffer
  		// First, we must read the entire request.
  		req, err := http.ReadRequest(bufio.NewReader(
  			io.TeeReader(conn, &buf),
  		))
  		if err == nil {
  			// Fulfill the buffer with the response body.
  			io.Copy(ioutil.Discard, req.Body)
  			req.Body.Close()
  		}
  		onRequest(buf.Bytes())
  
  		r = io.MultiReader(
  			&buf, conn,
  		)
  	}
  
  	if onResponse := d.OnResponse; onResponse != nil {
  		var buf bytes.Buffer
  		// Intercept the response stream written by the Upgrade().
  		w = io.MultiWriter(
  			conn, &buf,
  		)
  		defer func() {
  			onResponse(buf.Bytes())
  		}()
  	}
  
  	return d.Upgrader.Upgrade(struct {
  		io.Reader
  		io.Writer
  	}{r, w})
  }
docs: // Upgrade calls Upgrade() on underlying ws.Upgrader and tracks I/O on conn.