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)
| 2495 | // As a special case, handleResponse may return (nil, nil) to skip the |
| 2496 | // frame (currently only used for 1xx responses). |
| 2497 | func (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 { |
no test coverage detected