public async Task HandlePlaybackRequest(string recordingId, HttpRequest incomingRequest, HttpResponse outgoingResponse) { await DebugLogger.LogRequestDetailsAsync(incomingRequest); if (!PlaybackSessions.TryGetValue(recordingId, out var session)) { throw new HttpException(HttpStatusCode.BadRequest, $"There is no active playback session under recording id {recordingId}."); } var entry = await CreateEntryAsync(incomingRequest).ConfigureAwait(false); // If request contains "x-recording-remove: false", then request is not removed from session after playback. // Used by perf tests to play back the same request multiple times. var remove = true; if (incomingRequest.Headers.TryGetValue("x-recording-remove", out var removeHeader)) { remove = bool.Parse(removeHeader); } var match = session.Session.Lookup(entry, session.CustomMatcher ?? Matcher, session.AdditionalSanitizers.Count > 0 ? Sanitizers.Concat(session.AdditionalSanitizers) : Sanitizers, remove); foreach (ResponseTransform transform in Transforms.Concat(session.AdditionalTransforms)) { transform.Transform(incomingRequest, match); } Interlocked.Increment(ref Startup.RequestsPlayedBack); outgoingResponse.StatusCode = match.StatusCode; foreach (var header in match.Response.Headers) { outgoingResponse.Headers.Add(header.Key, header.Value.ToArray()); } outgoingResponse.Headers.Remove("Transfer-Encoding"); if (match.Response.Body?.Length > 0) { var bodyData = CompressBody(match.Response.Body, match.Response.Headers); outgoingResponse.ContentLength = bodyData.Length; await outgoingResponse.Body.WriteAsync(bodyData).ConfigureAwait(false); } }