MCPcopy
hub / github.com/grpc/grpc-go / operateHeaders

Method operateHeaders

internal/transport/http2_client.go:1471–1668  ·  view source on GitHub ↗

operateHeaders takes action on the decoded headers.

(frame *http2.MetaHeadersFrame)

Source from the content-addressed store, hash-verified

1469
1470// operateHeaders takes action on the decoded headers.
1471func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) {
1472 s := t.getStream(frame)
1473 if s == nil {
1474 return
1475 }
1476 endStream := frame.StreamEnded()
1477 s.bytesReceived.Store(true)
1478 initialHeader := atomic.LoadUint32(&s.headerChanClosed) == 0
1479
1480 if !initialHeader && !endStream {
1481 // As specified by gRPC over HTTP2, a HEADERS frame (and associated CONTINUATION frames) can only appear at the start or end of a stream. Therefore, second HEADERS frame must have EOS bit set.
1482 st := status.New(codes.Internal, "a HEADERS frame cannot appear in the middle of a stream")
1483 t.closeStream(s, st.Err(), true, http2.ErrCodeProtocol, st, nil, false)
1484 return
1485 }
1486
1487 // frame.Truncated is set to true when framer detects that the current header
1488 // list size hits MaxHeaderListSize limit.
1489 if frame.Truncated {
1490 se := status.New(codes.Internal, "peer header list size exceeded limit")
1491 t.closeStream(s, se.Err(), true, http2.ErrCodeFrameSize, se, nil, endStream)
1492 return
1493 }
1494
1495 // If we are collecting non-gRPC response data and receive a trailing
1496 // HEADERS frame with END_STREAM, finalize the buffered data and close
1497 // the stream.
1498 if s.nonGRPCStatus != nil {
1499 if endStream {
1500 st := s.finalizeNonGRPCStatus()
1501 t.closeStream(s, st.Err(), true, http2.ErrCodeProtocol, st, nil, true)
1502 }
1503 return
1504 }
1505
1506 var (
1507 // If a gRPC Response-Headers has already been received, then it means
1508 // that the peer is speaking gRPC and we are in gRPC mode.
1509 isGRPC = !initialHeader
1510 mdata = make(map[string][]string)
1511 contentTypeErr = "malformed header: missing HTTP content-type"
1512 grpcMessage string
1513 recvCompress string
1514 httpStatusErr string
1515 // the code from the grpc-status header, if present
1516 grpcStatusCode = codes.Unknown
1517 // headerError is set if an error is encountered while parsing the headers
1518 headerError string
1519 httpStatus string
1520 )
1521
1522 for _, hf := range frame.Fields {
1523 switch hf.Name {
1524 case "content-type":
1525 if _, validContentType := grpcutil.ContentSubtype(hf.Value); !validContentType {
1526 contentTypeErr = fmt.Sprintf("transport: received unexpected content-type %q", hf.Value)
1527 break
1528 }

Callers 1

readerMethod · 0.95

Calls 15

getStreamMethod · 0.95
closeStreamMethod · 0.95
ContentSubtypeFunction · 0.92
CodeTypeAlias · 0.92
MDTypeAlias · 0.92
decodeGrpcMessageFunction · 0.85
isReservedHeaderFunction · 0.85
isWhitelistedHeaderFunction · 0.85
decodeMetadataHeaderFunction · 0.85
StreamEndedMethod · 0.80
ErrMethod · 0.80
finalizeNonGRPCStatusMethod · 0.80

Tested by

no test coverage detected