You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: client.go
    path of file: ./repos/req/internal/http3
    
    the code of the file until where you have to start completion: package http3

import (
	"context"
	"crypto/tls"
	"errors"
	"fmt"
	"io"
	"net"
	"net/http"
	"strconv"
	"sync"
	"sync/atomic"
	"time"

	"github.com/imroc/req/v3/internal/dump"
	"github.com/imroc/req/v3/internal/quic-go/quicvarint"
	"github.com/imroc/req/v3/internal/transport"
	"github.com/quic-go/qpack"
	"github.com/quic-go/quic-go"
)

// Metho
    
func (c *client) doRequest(req *http.Request, conn quic.EarlyConnection, str quic.Stream, opt RoundTripOpt, reqDone chan<- struct{}) (*http.Response, requestError) {
	var requestGzip bool
	if !c.opts.DisableCompression && req.Method != "HEAD" && req.Header.Get("Accept-Encoding") == "" && req.Header.Get("Range") == "" {
		requestGzip = true
	}
	dumps := dump.GetDumpers(req.Context(), c.opts.dump)
	var headerDumps []*dump.Dumper
	for _, dump := range dumps {
		if dump.RequestHeader() {
			headerDumps = append(headerDumps, dump)
		}
	}
	if err := c.requestWriter.WriteRequestHeader(str, req, requestGzip, headerDumps); err != nil {
		return nil, newStreamError(ErrCodeInternalError, err)
	}

	if req.Body == nil && !opt.DontCloseRequestStream {
		str.Close()
	}

	hstr := newStream(str, func() { conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameUnexpected), "") })
	if req.Body != nil {
		// send the request body asynchronously
		go func() {
			var bodyDumps []*dump.Dumper
			for _, dump := range dumps {
				if dump.RequestBody() {
					bodyDumps = append(bodyDumps, dump)
				}
			}
			if err := c.sendRequestBody(hstr, req.Body, bodyDumps); err != nil {
				c.opt.Debugf("error writing request: %s", err)
			}
			if !opt.DontCloseRequestStream {
				hstr.Close()
			}
		}()
	}

	frame, err := parseNextFrame(str, nil)
	if err != nil {
		return nil, newStreamError(ErrCodeFrameError, err)
	}
	hf, ok := frame.(*headersFrame)
	if !ok {
		return nil, newConnError(ErrCodeFrameUnexpected, errors.New("expected first frame to be a HEADERS frame"))
	}
	if hf.Length > c.maxHeaderBytes() {
		return nil, newStreamError(ErrCodeFrameError, fmt.Errorf("HEADERS frame too large: %d bytes (max: %d)", hf.Length, c.maxHeaderBytes()))
	}
	headerBlock := make([]byte, hf.Length)
	if _, err := io.ReadFull(str, headerBlock); err != nil {
		return nil, newStreamError(ErrCodeRequestIncomplete, err)
	}
	var respHeaderDumps []*dump.Dumper
	for _, dump := range dumps {
		if dump.ResponseHeader() {
			respHeaderDumps = append(respHeaderDumps, dump)
		}
	}
	hfs, err := c.decoder.DecodeFull(headerBlock)
	if len(respHeaderDumps) > 0 {
		for _, hf := range hfs {
			for _, dump := range respHeaderDumps {
				dump.DumpResponseHeader([]byte(fmt.Sprintf("%s: %s\r\n", hf.Name, hf.Value)))
			}
		}
		for _, dump := range respHeaderDumps {
			dump.DumpResponseHeader([]byte("\r\n"))
		}
	}
	if err != nil {
		// TODO: use the right error code
		return nil, newConnError(ErrCodeGeneralProtocolError, err)
	}

	res, err := responseFromHeaders(hfs)
	if err != nil {
		return nil, newStreamError(ErrCodeMessageError, err)
	}
	res.Request = req
	connState := conn.ConnectionState().TLS
	res.TLS = &connState
	respBody := newResponseBody(hstr, conn, reqDone)

	// Rules for when to set Content-Length are defined in https://tools.ietf.org/html/rfc7230#section-3.3.2.
	_, hasTransferEncoding := res.Header["Transfer-Encoding"]
	isInformational := res.StatusCode >= 100 && res.StatusCode < 200
	isNoContent := res.StatusCode == http.StatusNoContent
	isSuccessfulConnect := req.Method == http.MethodConnect && res.StatusCode >= 200 && res.StatusCode < 300
	if !hasTransferEncoding && !isInformational && !isNoContent && !isSuccessfulConnect {
		res.ContentLength = -1
		if clens, ok := res.Header["Content-Length"]; ok && len(clens) == 1 {
			if clen64, err := strconv.ParseInt(clens[0], 10, 64); err == nil {
				res.ContentLength = clen64
			}
		}
	}

	if requestGzip && res.Header.Get("Content-Encoding") == "gzip" {
		res.Header.Del("Content-Encoding")
		res.Header.Del("Content-Length")
		res.ContentLength = -1
		res.Body = newGzipReader(respBody)
		res.Uncompressed = true
	} else {
		res.Body = respBody
	}

	return res, requestError{}
}