send method

  1. @override
Future<StreamedResponse> send(
  1. BaseRequest request
)

Simulates an HTTP request and response.

Makes a real request and records the response if the Mode is Mode.record. Drops the request and returns a recorded response if the Mode is Mode.replay. Makes a real request and returns the real response if the Mode is Mode.bypass. Either makes a real request and records the response, or drops the request and returns a recorded response if the Mode is Mode.auto.

Implementation

@override
Future<http.StreamedResponse> send(http.BaseRequest request) async {
  switch (_mode) {
    case Mode.record:
      // make real request, record response
      return _recordRequestAndResponse(request);

    case Mode.replay:
      // try to get recorded request, fallback to exception
      HttpInteraction? replayInteraction = _findMatchingInteraction(request);
      if (replayInteraction == null) {
        throw VCRException(
            "No matching interaction found for request ${request.method} ${request.url}");
      }
      if (_advancedOptions.validTimeFrame
          .hasLapsed(replayInteraction.recordedAt)) {
        switch (_advancedOptions.whenExpired) {
          case ExpirationAction.warn:
            // just throw a warning
            // will still simulate delay below
            print("WARNING: Matching interaction has expired");
            break;
          case ExpirationAction.throwException:
            // throw an exception and exit this function
            throw VCRException("Matching interaction has expired");
          case ExpirationAction.recordAgain:
            // we should never get here, the settings check should catch this during construction
            throw VCRException(
                "Cannot re-record an expired interaction in Replay mode.");
        }
      }

      // simulate delay if configured
      await _simulateDelay(replayInteraction);
      // return matching interaction's response
      return replayInteraction.toStreamedResponse(_advancedOptions.censors);

    case Mode.auto:
      // try to get recorded request, fallback to live request + record
      HttpInteraction? replayInteraction = _findMatchingInteraction(request);
      if (replayInteraction != null) {
        // found a matching interaction
        if (_advancedOptions.validTimeFrame
            .hasLapsed(replayInteraction.recordedAt)) {
          // interaction has expired
          switch (_advancedOptions.whenExpired) {
            case ExpirationAction.warn:
              // just throw a warning
              // will still simulate delay below
              print("WARNING: Matching interaction has expired");
              break;
            case ExpirationAction.throwException:
              // throw an exception and exit this function
              throw VCRException("Matching interaction has expired");
            case ExpirationAction.recordAgain:
              //  re-record over expired interaction
              // this will not execute the simulated delay, but since it's making a live request, a real delay will happen.
              return _recordRequestAndResponse(request);
          }
        }
        // simulate delay if configured
        await _simulateDelay(replayInteraction);
        // return matching interaction's response
        return replayInteraction.toStreamedResponse(_advancedOptions.censors);
      }

      // no matching interaction found, make real request, record response
      return _recordRequestAndResponse(request);

    case Mode.bypass:
      // make real request, don't record response
      return _client.send(request);
  }
}