func()

in garbage/nethttp.go [7370:7464]


func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err error) {
	if hook := testHookEnterRoundTrip; hook != nil {
		hook()
	}
	if !pc.t.replaceReqCanceler(req.Request, pc.cancelRequest) {
		pc.t.putIdleConn(pc)
		return nil, errRequestCanceled
	}
	pc.lk.Lock()
	pc.numExpectedResponses++
	headerFn := pc.mutateHeaderFunc
	pc.lk.Unlock()

	if headerFn != nil {
		headerFn(req.extraHeaders())
	}

	requestedGzip := false
	if !pc.t.DisableCompression &&
		req.Header.Get("Accept-Encoding") == "" &&
		req.Header.Get("Range") == "" &&
		req.Method != "HEAD" {

		requestedGzip = true
		req.extraHeaders().Set("Accept-Encoding", "gzip")
	}

	if pc.t.DisableKeepAlives {
		req.extraHeaders().Set("Connection", "close")
	}

	writeErrCh := make(chan error, 1)
	pc.writech <- writeRequest{req, writeErrCh}

	resc := make(chan responseAndError, 1)
	pc.reqch <- requestAndChan{req.Request, resc, requestedGzip}

	var re responseAndError
	var respHeaderTimer <-chan time.Time
	cancelChan := req.Request.Cancel
WaitResponse:
	for {
		select {
		case err := <-writeErrCh:
			if isNetWriteError(err) {

				select {
				case re = <-resc:
					pc.close()
					break WaitResponse
				case <-time.After(50 * time.Millisecond):

				}
			}
			if err != nil {
				re = responseAndError{nil, err}
				pc.close()
				break WaitResponse
			}
			if d := pc.t.ResponseHeaderTimeout; d > 0 {
				timer := time.NewTimer(d)
				defer timer.Stop()
				respHeaderTimer = timer.C
			}
		case <-pc.closech:

			select {
			case re = <-resc:
				if fn := testHookPersistConnClosedGotRes; fn != nil {
					fn()
				}
			default:
				re = responseAndError{err: errClosed}
				if pc.isCanceled() {
					re = responseAndError{err: errRequestCanceled}
				}
			}
			break WaitResponse
		case <-respHeaderTimer:
			pc.close()
			re = responseAndError{err: errTimeout}
			break WaitResponse
		case re = <-resc:
			break WaitResponse
		case <-cancelChan:
			pc.t.CancelRequest(req.Request)
			cancelChan = nil
		}
	}

	if re.err != nil {
		pc.t.setReqCanceler(req.Request, nil)
	}
	return re.res, re.err
}