send method
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);
}
}