ParseResult HQControlCodec::checkFrameAllowed()

in proxygen/lib/http/codec/HQControlCodec.cpp [34:78]


ParseResult HQControlCodec::checkFrameAllowed(FrameType type) {
  switch (type) {
    case hq::FrameType::DATA:
    case hq::FrameType::HEADERS:
    case hq::FrameType::PUSH_PROMISE:
      return HTTP3::ErrorCode::HTTP_FRAME_UNEXPECTED;
    default:
      break;
  }

  if (getStreamType() == hq::UnidirectionalStreamType::CONTROL) {
    // SETTINGS MUST be the first frame on an HQ Control Stream
    if (!receivedSettings_ && type != hq::FrameType::SETTINGS) {
      return HTTP3::ErrorCode::HTTP_MISSING_SETTINGS;
    }
    // multiple SETTINGS frames are not allowed
    if (receivedSettings_ && type == hq::FrameType::SETTINGS) {
      return HTTP3::ErrorCode::HTTP_FRAME_UNEXPECTED;
    }
    // A client MUST treat the receipt of a MAX_PUSH_ID frame as a connection
    // error of type HTTP_FRAME_UNEXPECTED
    if (transportDirection_ == TransportDirection::UPSTREAM &&
        type == hq::FrameType::MAX_PUSH_ID) {
      return HTTP3::ErrorCode::HTTP_FRAME_UNEXPECTED;
    }

    // PRIORITY_UPDATE is downstream control codec only
    if (transportDirection_ == TransportDirection::UPSTREAM &&
        (type == hq::FrameType::PRIORITY_UPDATE ||
         type == hq::FrameType::PUSH_PRIORITY_UPDATE ||
         type == hq::FrameType::FB_PUSH_PRIORITY_UPDATE ||
         type == hq::FrameType::FB_PRIORITY_UPDATE)) {
      return HTTP3::ErrorCode::HTTP_FRAME_UNEXPECTED;
    }
  }

  // Only GOAWAY from Server to Client are allowed in H1Q
  if (getStreamType() == hq::UnidirectionalStreamType::H1Q_CONTROL &&
      (transportDirection_ == TransportDirection::DOWNSTREAM ||
       type != hq::FrameType::GOAWAY)) {
    return HTTP3::ErrorCode::HTTP_FRAME_UNEXPECTED;
  }

  return folly::none;
}