public static EntryRecordMode GetRecordMode(HttpRequest request)
        {
            EntryRecordMode mode = EntryRecordMode.Record;

            if (request.Headers.TryGetValue(SkipRecordingHeaderKey, out var values))
            {
                if (values.Count != 1)
                {
                    throw new HttpException(
                              HttpStatusCode.BadRequest,
                              $"'{SkipRecordingHeaderKey}' should contain a single value set to either '{SkipRecordingRequestBody}' or " +
                              $"'{SkipRecordingRequestResponse}'");
                }
                string skipMode = values.First();
                if (skipMode.Equals(SkipRecordingRequestResponse, StringComparison.OrdinalIgnoreCase))
                {
                    mode = EntryRecordMode.DontRecord;
                }
                else if (skipMode.Equals(SkipRecordingRequestBody, StringComparison.OrdinalIgnoreCase))
                {
                    mode = EntryRecordMode.RecordWithoutRequestBody;
                }
                else
                {
                    throw new HttpException(
                              HttpStatusCode.BadRequest,
                              $"{skipMode} is not a supported value for header '{SkipRecordingHeaderKey}'." +
                              $"It should be either omitted from the request headers, or set to either '{SkipRecordingRequestBody}' " +
                              $"or '{SkipRecordingRequestResponse}'");
                }
            }

            return(mode);
        }
Beispiel #2
0
        public void Stop([FromBody()] IDictionary <string, string> variables = null)
        {
            string          id   = RecordingHandler.GetHeader(Request, "x-recording-id");
            bool            save = true;
            EntryRecordMode mode = RecordingHandler.GetRecordMode(Request);

            if (mode != EntryRecordMode.Record && mode != EntryRecordMode.DontRecord)
            {
                throw new HttpException(HttpStatusCode.BadRequest, "When stopping a recording and providing a \"x-recording-skip\" value, only value \"request-response\" is accepted.");
            }

            if (mode == EntryRecordMode.DontRecord)
            {
                save = false;
            }

            _recordingHandler.StopRecording(id, variables: variables, saveRecording: save);
        }
        public async Task HandleRecordRequestAsync(string recordingId, HttpRequest incomingRequest, HttpResponse outgoingResponse)
        {
            await DebugLogger.LogRequestDetailsAsync(incomingRequest);

            if (!RecordingSessions.TryGetValue(recordingId, out var session))
            {
                throw new HttpException(HttpStatusCode.BadRequest, $"There is no active recording session under id {recordingId}.");
            }

            var entry = await CreateEntryAsync(incomingRequest).ConfigureAwait(false);

            var upstreamRequest = CreateUpstreamRequest(incomingRequest, entry.Request.Body);

            HttpResponseMessage upstreamResponse = null;

            if (HandleRedirects)
            {
                upstreamResponse = await(session.Client ?? RedirectableClient).SendAsync(upstreamRequest).ConfigureAwait(false);
            }
            else
            {
                upstreamResponse = await(session.Client ?? RedirectlessClient).SendAsync(upstreamRequest).ConfigureAwait(false);
            }

            byte[] body = Array.Empty <byte>();

            // HEAD requests do NOT have a body regardless of the value of the Content-Length header
            if (incomingRequest.Method.ToUpperInvariant() != "HEAD")
            {
                body = DecompressBody((MemoryStream)await upstreamResponse.Content.ReadAsStreamAsync().ConfigureAwait(false), upstreamResponse.Content.Headers);
            }

            entry.Response.Body = body.Length == 0 ? null : body;
            entry.StatusCode    = (int)upstreamResponse.StatusCode;

            EntryRecordMode mode = GetRecordMode(incomingRequest);

            if (mode != EntryRecordMode.DontRecord)
            {
                session.Session.Entries.Add(entry);

                Interlocked.Increment(ref Startup.RequestsRecorded);
            }

            if (mode == EntryRecordMode.RecordWithoutRequestBody)
            {
                entry.Request.Body = null;
            }

            outgoingResponse.StatusCode = (int)upstreamResponse.StatusCode;
            foreach (var header in upstreamResponse.Headers.Concat(upstreamResponse.Content.Headers))
            {
                var values = new StringValues(header.Value.ToArray());
                outgoingResponse.Headers.Add(header.Key, values);
                entry.Response.Headers.Add(header.Key, values);
            }

            outgoingResponse.Headers.Remove("Transfer-Encoding");

            if (entry.Response.Body?.Length > 0)
            {
                var bodyData = CompressBody(entry.Response.Body, entry.Response.Headers);
                outgoingResponse.ContentLength = bodyData.Length;
                await outgoingResponse.Body.WriteAsync(bodyData).ConfigureAwait(false);
            }
        }