void requestAction(StreamState& state, const test::common::http::RequestAction& request_action) {
    switch (request_action.request_action_selector_case()) {
    case test::common::http::RequestAction::kData: {
      if (state == StreamState::PendingDataOrTrailers) {
        const auto& data_action = request_action.data();
        ON_CALL(*decoder_filter_, decodeData(_, _))
            .WillByDefault(InvokeWithoutArgs([this, &data_action]() -> Http::FilterDataStatus {
              if (data_action.has_decoder_filter_callback_action()) {
                decoderFilterCallbackAction(data_action.decoder_filter_callback_action());
              }
              data_status_ = fromDataStatus(data_action.status());
              return *data_status_;
            }));
        EXPECT_CALL(*config_.codec_, dispatch(_)).WillOnce(InvokeWithoutArgs([this, &data_action] {
          Buffer::OwnedImpl buf(std::string(data_action.size() % (1024 * 1024), 'a'));
          decoder_->decodeData(buf, data_action.end_stream());
          return Http::okStatus();
        }));
        fakeOnData();
        FUZZ_ASSERT(testing::Mock::VerifyAndClearExpectations(config_.codec_));
        state = data_action.end_stream() ? StreamState::Closed : StreamState::PendingDataOrTrailers;
      }
      break;
    }
    case test::common::http::RequestAction::kTrailers: {
      if (state == StreamState::PendingDataOrTrailers) {
        const auto& trailers_action = request_action.trailers();
        ON_CALL(*decoder_filter_, decodeTrailers(_))
            .WillByDefault(
                InvokeWithoutArgs([this, &trailers_action]() -> Http::FilterTrailersStatus {
                  if (trailers_action.has_decoder_filter_callback_action()) {
                    decoderFilterCallbackAction(trailers_action.decoder_filter_callback_action());
                  }
                  return fromTrailerStatus(trailers_action.status());
                }));
        EXPECT_CALL(*config_.codec_, dispatch(_))
            .WillOnce(InvokeWithoutArgs([this, &trailers_action] {
              decoder_->decodeTrailers(std::make_unique<TestRequestTrailerMapImpl>(
                  Fuzz::fromHeaders<TestRequestTrailerMapImpl>(trailers_action.headers())));
              return Http::okStatus();
            }));
        fakeOnData();
        FUZZ_ASSERT(testing::Mock::VerifyAndClearExpectations(config_.codec_));
        state = StreamState::Closed;
      }
      break;
    }
    case test::common::http::RequestAction::kContinueDecoding: {
      if (header_status_ == FilterHeadersStatus::StopAllIterationAndBuffer ||
          header_status_ == FilterHeadersStatus::StopAllIterationAndWatermark ||
          (header_status_ == FilterHeadersStatus::StopIteration &&
           (data_status_ == FilterDataStatus::StopIterationAndBuffer ||
            data_status_ == FilterDataStatus::StopIterationAndWatermark ||
            data_status_ == FilterDataStatus::StopIterationNoBuffer))) {
        decoder_filter_->callbacks_->continueDecoding();
      }
      break;
    }
    case test::common::http::RequestAction::kThrowDecoderException:
    // Dispatch no longer throws, execute subsequent kReturnDecoderError case.
    case test::common::http::RequestAction::kReturnDecoderError: {
      if (state == StreamState::PendingDataOrTrailers) {
        EXPECT_CALL(*config_.codec_, dispatch(_))
            .WillOnce(testing::Return(codecProtocolError("blah")));
        fakeOnData();
        FUZZ_ASSERT(testing::Mock::VerifyAndClearExpectations(config_.codec_));
        state = StreamState::Closed;
      }
      break;
    }
    default:
      // Maybe nothing is set or not a request action?
      break;
    }
  }