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

Method handleResponse

internal/http2/transport.go:2497–2624  ·  view source on GitHub ↗

may return error types nil, or ConnectionError. Any other error value is a StreamError of type ErrCodeProtocol. The returned error in that case is the detail. As a special case, handleResponse may return (nil, nil) to skip the frame (currently only used for 1xx responses).

(cs *clientStream, f *MetaHeadersFrame)

Source from the content-addressed store, hash-verified

2495// As a special case, handleResponse may return (nil, nil) to skip the
2496// frame (currently only used for 1xx responses).
2497func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFrame) (*http.Response, error) {
2498 if f.Truncated {
2499 return nil, errResponseHeaderListSize
2500 }
2501
2502 status := f.PseudoValue("status")
2503 if status == "" {
2504 return nil, errors.New("malformed response from server: missing status pseudo header")
2505 }
2506 statusCode, err := strconv.Atoi(status)
2507 if err != nil {
2508 return nil, errors.New("malformed response from server: malformed non-numeric status pseudo header")
2509 }
2510
2511 regularFields := f.RegularFields()
2512 strs := make([]string, len(regularFields))
2513 header := make(http.Header, len(regularFields))
2514 res := &http.Response{
2515 Proto: "HTTP/2.0",
2516 ProtoMajor: 2,
2517 Header: header,
2518 StatusCode: statusCode,
2519 Status: status + " " + http.StatusText(statusCode),
2520 }
2521 for _, hf := range regularFields {
2522 key := canonicalHeader(hf.Name)
2523 if key == "Trailer" {
2524 t := res.Trailer
2525 if t == nil {
2526 t = make(http.Header)
2527 res.Trailer = t
2528 }
2529 foreachHeaderElement(hf.Value, func(v string) {
2530 t[canonicalHeader(v)] = nil
2531 })
2532 } else {
2533 vv := header[key]
2534 if vv == nil && len(strs) > 0 {
2535 // More than likely this will be a single-element key.
2536 // Most headers aren't multi-valued.
2537 // Set the capacity on strs[0] to 1, so any future append
2538 // won't extend the slice into the other strings.
2539 vv, strs = strs[:1:1], strs[1:]
2540 vv[0] = hf.Value
2541 header[key] = vv
2542 } else {
2543 header[key] = append(vv, hf.Value)
2544 }
2545 }
2546 }
2547
2548 if statusCode >= 100 && statusCode <= 199 {
2549 if f.StreamEnded() {
2550 return nil, errors.New("1xx informational response with END_STREAM flag")
2551 }
2552 cs.num1xx++
2553 const max1xxResponses = 5 // arbitrary bound on number of informational responses, same as net/http
2554 if cs.num1xx > max1xxResponses {

Callers 1

processHeadersMethod · 0.95

Calls 12

EqualFoldFunction · 0.92
NewGzipReaderFunction · 0.92
NewCompressReaderFunction · 0.92
canonicalHeaderFunction · 0.85
PseudoValueMethod · 0.80
RegularFieldsMethod · 0.80
get1xxTraceFuncMethod · 0.80
setBufferMethod · 0.80
foreachHeaderElementFunction · 0.70
traceGot100ContinueFunction · 0.70
StreamEndedMethod · 0.65
GetMethod · 0.45

Tested by

no test coverage detected