MCPcopy Create free account
hub / github.com/imroc/req / doRequest

Method doRequest

internal/http3/client.go:340–408  ·  view source on GitHub ↗
(req *http.Request, str *RequestStream)

Source from the content-addressed store, hash-verified

338}
339
340func (c *ClientConn) doRequest(req *http.Request, str *RequestStream) (*http.Response, error) {
341 trace := httptrace.ContextClientTrace(req.Context())
342 var sendingReqFailed bool
343 if err := str.sendRequestHeader(req); err != nil {
344 traceWroteRequest(trace, err)
345 if c.logger != nil {
346 c.logger.Debug("error writing request", "error", err)
347 }
348 sendingReqFailed = true
349 }
350 if !sendingReqFailed {
351 if req.Body == nil {
352 traceWroteRequest(trace, nil)
353 str.Close()
354 } else {
355 // send the request body asynchronously
356 go func() {
357 contentLength := int64(-1)
358 // According to the documentation for http.Request.ContentLength,
359 // a value of 0 with a non-nil Body is also treated as unknown content length.
360 if req.ContentLength > 0 {
361 contentLength = req.ContentLength
362 }
363 dumps := dump.GetDumpers(req.Context(), c.Dump)
364 err := c.sendRequestBody(str, req.Body, contentLength, dumps)
365 traceWroteRequest(trace, err)
366 if err != nil {
367 if c.logger != nil {
368 c.logger.Debug("error writing request", "error", err)
369 }
370 }
371 str.Close()
372 }()
373 }
374 }
375
376 // copy from net/http: support 1xx responses
377 var num1xx int // number of informational 1xx headers received
378 var res *http.Response
379 for {
380 var err error
381 res, err = str.ReadResponse()
382 if err != nil {
383 return nil, err
384 }
385 resCode := res.StatusCode
386 is1xx := 100 <= resCode && resCode <= 199
387 // treat 101 as a terminal status, see https://github.com/golang/go/issues/26161
388 is1xxNonTerminal := is1xx && resCode != http.StatusSwitchingProtocols
389 if is1xxNonTerminal {
390 num1xx++
391 if num1xx > max1xxResponses {
392 str.CancelRead(quic.StreamErrorCode(ErrCodeExcessiveLoad))
393 str.CancelWrite(quic.StreamErrorCode(ErrCodeExcessiveLoad))
394 return nil, errors.New("http3: too many 1xx informational responses")
395 }
396 traceGot1xxResponse(trace, resCode, textproto.MIMEHeader(res.Header))
397 if resCode == http.StatusContinue {

Callers 1

roundTripMethod · 0.95

Calls 12

sendRequestBodyMethod · 0.95
GetDumpersFunction · 0.92
traceGot1xxResponseFunction · 0.85
sendRequestHeaderMethod · 0.80
ReadResponseMethod · 0.80
traceWroteRequestFunction · 0.70
traceGot100ContinueFunction · 0.70
ContextMethod · 0.65
CancelReadMethod · 0.65
CancelWriteMethod · 0.65
ConnectionStateMethod · 0.65
CloseMethod · 0.45

Tested by

no test coverage detected