ReadResponse reads the HTTP response from the stream. It must be called after sending the request (using SendRequestHeader). It is invalid to call it more than once. It doesn't set Response.Request and Response.TLS. It is invalid to call it after Read has been called.
()
| 328 | // It doesn't set Response.Request and Response.TLS. |
| 329 | // It is invalid to call it after Read has been called. |
| 330 | func (s *RequestStream) ReadResponse() (*http.Response, error) { |
| 331 | if !s.sentRequest { |
| 332 | return nil, errors.New("http3: invalid duplicate use of RequestStream.ReadResponse before SendRequestHeader") |
| 333 | } |
| 334 | frame, err := s.str.frameParser.ParseNext(s.str.qlogger) |
| 335 | if err != nil { |
| 336 | s.str.CancelRead(quic.StreamErrorCode(ErrCodeFrameError)) |
| 337 | s.str.CancelWrite(quic.StreamErrorCode(ErrCodeFrameError)) |
| 338 | return nil, fmt.Errorf("http3: parsing frame failed: %w", err) |
| 339 | } |
| 340 | hf, ok := frame.(*headersFrame) |
| 341 | if !ok { |
| 342 | s.str.conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameUnexpected), "expected first frame to be a HEADERS frame") |
| 343 | return nil, errors.New("http3: expected first frame to be a HEADERS frame") |
| 344 | } |
| 345 | if hf.Length > uint64(s.maxHeaderBytes) { |
| 346 | maybeQlogInvalidHeadersFrame(s.str.qlogger, s.str.StreamID(), hf.Length) |
| 347 | s.str.CancelRead(quic.StreamErrorCode(ErrCodeFrameError)) |
| 348 | s.str.CancelWrite(quic.StreamErrorCode(ErrCodeFrameError)) |
| 349 | return nil, fmt.Errorf("http3: HEADERS frame too large: %d bytes (max: %d)", hf.Length, s.maxHeaderBytes) |
| 350 | } |
| 351 | headerBlock := make([]byte, hf.Length) |
| 352 | if _, err := io.ReadFull(s.str.datagramStream, headerBlock); err != nil { |
| 353 | maybeQlogInvalidHeadersFrame(s.str.qlogger, s.str.StreamID(), hf.Length) |
| 354 | s.str.CancelRead(quic.StreamErrorCode(ErrCodeRequestIncomplete)) |
| 355 | s.str.CancelWrite(quic.StreamErrorCode(ErrCodeRequestIncomplete)) |
| 356 | return nil, fmt.Errorf("http3: failed to read response headers: %w", err) |
| 357 | } |
| 358 | decodeFn := s.decoder.Decode(headerBlock) |
| 359 | var hfs []qpack.HeaderField |
| 360 | if s.str.qlogger != nil { |
| 361 | hfs = make([]qpack.HeaderField, 0, 16) |
| 362 | } |
| 363 | res := s.response |
| 364 | ds := dump.GetResponseHeaderDumpers(s.ctx, s.Dump) |
| 365 | err = updateResponseFromHeaders(res, decodeFn, s.maxHeaderBytes, &hfs, ds) |
| 366 | if s.str.qlogger != nil { |
| 367 | qlogParsedHeadersFrame(s.str.qlogger, s.str.StreamID(), hf, hfs) |
| 368 | } |
| 369 | if err != nil { |
| 370 | errCode := ErrCodeMessageError |
| 371 | var qpackErr *qpackError |
| 372 | if errors.As(err, &qpackErr) { |
| 373 | errCode = ErrCodeQPACKDecompressionFailed |
| 374 | } |
| 375 | s.str.CancelRead(quic.StreamErrorCode(errCode)) |
| 376 | s.str.CancelWrite(quic.StreamErrorCode(errCode)) |
| 377 | return nil, fmt.Errorf("http3: invalid response: %w", err) |
| 378 | } |
| 379 | |
| 380 | // Check that the server doesn't send more data in DATA frames than indicated by the Content-Length header (if set). |
| 381 | // See section 4.1.2 of RFC 9114. |
| 382 | respBody := newResponseBody(s.str, res.ContentLength, s.reqDone) |
| 383 | |
| 384 | // Rules for when to set Content-Length are defined in https://tools.ietf.org/html/rfc7230#section-3.3.2. |
| 385 | isInformational := res.StatusCode >= 100 && res.StatusCode < 200 |
| 386 | isNoContent := res.StatusCode == http.StatusNoContent |
| 387 | isSuccessfulConnect := s.isConnect && res.StatusCode >= 200 && res.StatusCode < 300 |
no test coverage detected