/// <inheritdoc /> public Task <StubResponseWriterResultModel> WriteToResponseAsync(StubModel stub, ResponseModel response) { if (stub.Response.EnableDynamicMode != true) { return(Task.FromResult(StubResponseWriterResultModel.IsNotExecuted(GetType().Name))); } // Try to parse and replace the variables in the body. if (!response.BodyIsBinary && response.Body != null) { var parsedBody = _responseVariableParser.Parse(Encoding.UTF8.GetString(response.Body)); response.Body = Encoding.UTF8.GetBytes(parsedBody); } // Try to parse and replace the variables in the header values. var keys = response.Headers.Keys.ToArray(); foreach (var key in keys) { response.Headers[key] = _responseVariableParser.Parse(response.Headers[key]); } return(Task.FromResult(StubResponseWriterResultModel.IsExecuted(GetType().Name))); }
/// <inheritdoc /> public Task <StubResponseWriterResultModel> WriteToResponseAsync(StubModel stub, ResponseModel response) { if (string.IsNullOrWhiteSpace(stub.Response?.ContentType)) { return(Task.FromResult(StubResponseWriterResultModel.IsNotExecuted(GetType().Name))); } response.Headers.AddOrReplaceCaseInsensitive("Content-Type", stub.Response.ContentType); return(Task.FromResult(StubResponseWriterResultModel.IsExecuted(GetType().Name))); }
/// <inheritdoc /> public Task <StubResponseWriterResultModel> WriteToResponseAsync(StubModel stub, ResponseModel response) { if (stub.Response.Scenario?.ClearState != true || string.IsNullOrWhiteSpace(stub.Scenario)) { return(Task.FromResult(StubResponseWriterResultModel.IsNotExecuted(GetType().Name))); } _scenarioService.DeleteScenario(stub.Scenario); return(Task.FromResult(StubResponseWriterResultModel.IsExecuted(GetType().Name))); }
/// <inheritdoc /> public Task <StubResponseWriterResultModel> WriteToResponseAsync(StubModel stub, ResponseModel response) { if (response.StatusCode != 0) { return(Task.FromResult(StubResponseWriterResultModel.IsNotExecuted(GetType().Name))); } response.StatusCode = stub.Response?.StatusCode ?? 200; return(Task.FromResult(StubResponseWriterResultModel.IsExecuted(GetType().Name))); }
/// <inheritdoc /> public Task <StubResponseWriterResultModel> WriteToResponseAsync(StubModel stub, ResponseModel response) { if (stub.Response.Text == null) { return(Task.FromResult(StubResponseWriterResultModel.IsNotExecuted(GetType().Name))); } response.Body = Encoding.UTF8.GetBytes(stub.Response.Text); response.Headers.AddOrReplaceCaseInsensitive("Content-Type", Constants.TextMime, false); return(Task.FromResult(StubResponseWriterResultModel.IsExecuted(GetType().Name))); }
/// <inheritdoc /> public Task <StubResponseWriterResultModel> WriteToResponseAsync(StubModel stub, ResponseModel response) { if (stub.Response?.Base64 == null) { return(Task.FromResult(StubResponseWriterResultModel.IsNotExecuted(GetType().Name))); } var base64Body = stub.Response.Base64; response.Body = Convert.FromBase64String(base64Body); response.BodyIsBinary = true; return(Task.FromResult(StubResponseWriterResultModel.IsExecuted(GetType().Name))); }
/// <inheritdoc /> public async Task <StubResponseWriterResultModel> WriteToResponseAsync(StubModel stub, ResponseModel response) { // Simulate sluggish response here, if configured. if (stub.Response?.ExtraDuration.HasValue != true) { return(StubResponseWriterResultModel.IsNotExecuted(GetType().Name)); } var duration = stub.Response.ExtraDuration.Value; await _asyncService.DelayAsync(duration); return(StubResponseWriterResultModel.IsExecuted(GetType().Name)); }
/// <inheritdoc /> public Task <StubResponseWriterResultModel> WriteToResponseAsync(StubModel stub, ResponseModel response) { if (string.IsNullOrWhiteSpace(stub.Response.Scenario?.SetScenarioState) || string.IsNullOrWhiteSpace(stub.Scenario)) { return(Task.FromResult(StubResponseWriterResultModel.IsNotExecuted(GetType().Name))); } var scenario = stub.Scenario; var scenarioState = _scenarioService.GetScenario(scenario) ?? new ScenarioStateModel(scenario); scenarioState.State = stub.Response.Scenario.SetScenarioState; _scenarioService.SetScenario(scenario, scenarioState); return(Task.FromResult(StubResponseWriterResultModel.IsExecuted(GetType().Name))); }
/// <inheritdoc /> public Task <StubResponseWriterResultModel> WriteToResponseAsync(StubModel stub, ResponseModel response) { var stubResponseHeaders = stub.Response?.Headers; if (stubResponseHeaders == null || stubResponseHeaders?.Any() != true) { return(Task.FromResult(StubResponseWriterResultModel.IsNotExecuted(GetType().Name))); } foreach (var header in stubResponseHeaders) { response.Headers.Add(header.Key, header.Value); } return(Task.FromResult(StubResponseWriterResultModel.IsExecuted(GetType().Name))); }
/// <inheritdoc /> public Task <StubResponseWriterResultModel> WriteToResponseAsync(StubModel stub, ResponseModel response) { if (stub.Response?.TemporaryRedirect != null) { var url = stub.Response.TemporaryRedirect; response.StatusCode = (int)HttpStatusCode.TemporaryRedirect; response.Headers.Add("Location", url); return(Task.FromResult(StubResponseWriterResultModel.IsExecuted(GetType().Name))); } if (stub.Response?.PermanentRedirect != null) { var url = stub.Response.PermanentRedirect; response.StatusCode = (int)HttpStatusCode.MovedPermanently; response.Headers.Add("Location", url); return(Task.FromResult(StubResponseWriterResultModel.IsExecuted(GetType().Name))); } return(Task.FromResult(StubResponseWriterResultModel.IsNotExecuted(GetType().Name))); }
/// <inheritdoc /> public Task <StubResponseWriterResultModel> WriteToResponseAsync(StubModel stub, ResponseModel response) { if (stub.Response?.File == null) { return(Task.FromResult(StubResponseWriterResultModel.IsNotExecuted(GetType().Name))); } string finalFilePath = null; if (_fileService.FileExists(stub.Response.File)) { finalFilePath = stub.Response.File; } else { // File doesn't exist, but might exist in the file root folder. var stubRootPaths = _stubRootPathResolver.GetStubRootPaths(); foreach (var path in stubRootPaths) { var tempPath = Path.Combine(path, stub.Response.File); if (_fileService.FileExists(tempPath)) { finalFilePath = tempPath; break; } } } if (finalFilePath == null) { return(Task.FromResult(StubResponseWriterResultModel.IsNotExecuted(GetType().Name))); } response.Body = _fileService.ReadAllBytes(finalFilePath); response.BodyIsBinary = true; return(Task.FromResult(StubResponseWriterResultModel.IsExecuted(GetType().Name))); }
/// <inheritdoc /> public Task <StubResponseWriterResultModel> WriteToResponseAsync(StubModel stub, ResponseModel response) { var lineEndings = stub.Response.LineEndings; if (lineEndings is null or LineEndingType.NotSet) { return(Task.FromResult(StubResponseWriterResultModel.IsNotExecuted(GetType().Name))); } var log = string.Empty; if (response.BodyIsBinary) { log = "The response body is binary; cannot replace line endings."; } else { switch (lineEndings) { case LineEndingType.Unix: response.Body = ReplaceLineEndings(response.Body, "\n"); break; case LineEndingType.Windows: response.Body = ReplaceLineEndings(response.Body, "\r\n"); break; default: log = $"Line ending type '{lineEndings}' is not supported. Options are '{LineEndingType.Unix}' and '{LineEndingType.Windows}'."; break; } } return(Task.FromResult(StubResponseWriterResultModel.IsExecuted(GetType().Name, log))); }
/// <inheritdoc /> public async Task <StubResponseWriterResultModel> WriteToResponseAsync(StubModel stub, ResponseModel response) { if (stub.Response.ReverseProxy == null || string.IsNullOrWhiteSpace(stub.Response.ReverseProxy.Url)) { return(StubResponseWriterResultModel.IsNotExecuted(GetType().Name)); } var proxyUrl = stub.Response.ReverseProxy.Url; var appendPath = stub.Response.ReverseProxy.AppendPath == true; if (appendPath) { proxyUrl = proxyUrl.EnsureEndsWith("/") + _httpContextService.Path.TrimStart('/'); if (!string.IsNullOrWhiteSpace(stub.Conditions?.Url?.Path)) { // If the path condition is set, make sure the configured path is stripped from the proxy URL var configuredPath = stub.Conditions.Url.Path; var index = proxyUrl.IndexOf(configuredPath, StringComparison.OrdinalIgnoreCase); if (index > -1) { proxyUrl = proxyUrl.Remove(index, configuredPath.Length); } } } if (stub.Response.ReverseProxy.AppendQueryString == true) { proxyUrl += _httpContextService.GetQueryString(); } var method = new HttpMethod(_httpContextService.Method); var request = new HttpRequestMessage(method, proxyUrl); var log = $"Performing {method} request to URL {proxyUrl}"; var originalHeaders = _httpContextService .GetHeaders(); var headers = originalHeaders .Where(h => !_excludedRequestHeaderNames.Contains(h.Key, StringComparer.OrdinalIgnoreCase)) .ToArray(); foreach (var header in headers) { request.Headers.Add(header.Key, header.Value); } if (method != HttpMethod.Get) { var requestBody = _httpContextService.GetBodyAsBytes(); if (requestBody.Any()) { request.Content = new ByteArrayContent(requestBody); var contentTypeHeader = originalHeaders.FirstOrDefault(h => h.Key.Equals("content-type", StringComparison.OrdinalIgnoreCase)); if (!string.IsNullOrWhiteSpace(contentTypeHeader.Value)) { request.Content.Headers.Add("Content-Type", contentTypeHeader.Value); } } } using var httpClient = _httpClientFactory.CreateClient("proxy"); using var responseMessage = await httpClient.SendAsync(request); var content = responseMessage.Content != null ? await responseMessage.Content.ReadAsByteArrayAsync() : Array.Empty <byte>(); var rawResponseHeaders = responseMessage.Headers .ToDictionary(h => h.Key, h => h.Value.First()); if (stub.Response.ReverseProxy.ReplaceRootUrl == true) { var contentAsString = Encoding.UTF8.GetString(content); var rootUrlParts = proxyUrl.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries); var rootUrl = $"{rootUrlParts[0]}//{rootUrlParts[1]}"; var httPlaceholderRootUrl = _httpContextService.RootUrl; if (appendPath && !string.IsNullOrWhiteSpace(stub.Conditions?.Url?.Path)) { httPlaceholderRootUrl += stub.Conditions.Url.Path.EnsureStartsWith("/"); } contentAsString = contentAsString.Replace(rootUrl, httPlaceholderRootUrl); content = Encoding.UTF8.GetBytes(contentAsString); rawResponseHeaders = rawResponseHeaders .ToDictionary(h => h.Key, h => h.Value.Replace(rootUrl, httPlaceholderRootUrl)); } response.Body = content; var contentHeaders = responseMessage.Content != null ? responseMessage.Content.Headers.ToDictionary(h => h.Key, h => h.Value.First()) : new Dictionary <string, string>(); var responseHeaders = rawResponseHeaders .Concat(contentHeaders) .Where(h => !_excludedResponseHeaderNames.Contains(h.Key, StringComparer.OrdinalIgnoreCase)) .ToArray(); foreach (var header in responseHeaders) { response.Headers.AddOrReplaceCaseInsensitive(header.Key, header.Value); } response.StatusCode = (int)responseMessage.StatusCode; return(StubResponseWriterResultModel.IsExecuted(GetType().Name, log)); }
/// <inheritdoc /> public async Task <StubResponseWriterResultModel> WriteToResponseAsync(StubModel stub, ResponseModel response) { var imgDefinition = stub.Response?.Image; if (imgDefinition == null || imgDefinition.Type == ResponseImageType.NotSet) { return(StubResponseWriterResultModel.IsNotExecuted(GetType().Name)); } var stubImage = stub.Response.Image; response.Headers.AddOrReplaceCaseInsensitive("Content-Type", stubImage.ContentTypeHeaderValue); var cacheFilePath = Path.Combine(_fileService.GetTempPath(), $"{stubImage.Hash}.bin"); byte[] bytes; if (_fileService.FileExists(cacheFilePath)) { bytes = _fileService.ReadAllBytes(cacheFilePath); } else { var collection = new FontCollection(); collection.Install(Path.Combine(_assemblyService.GetExecutingAssemblyRootPath(), "Manrope-Regular.ttf")); const string fontFamilyName = "Manrope"; if (!collection.TryFind(fontFamilyName, out var family)) { throw new RequestValidationException($"Font family '{fontFamilyName}' not found!"); } using var image = new Image <Rgba32>(stubImage.Width, stubImage.Height); var font = new Font(family, stubImage.FontSize); var parsedColor = Color.ParseHex(stubImage.BackgroundColor); var polygon = new Rectangle(0, 0, stubImage.Width, stubImage.Height); var fontColor = !string.IsNullOrWhiteSpace(stubImage.FontColor) ? Color.ParseHex(stubImage.FontColor) : parsedColor.InvertColor(); image.Mutate(i => i .Fill(parsedColor, polygon) .ApplyScalingWaterMark(font, stubImage.Text, fontColor, 5, stubImage.WordWrap)); using var ms = new MemoryStream(); switch (stubImage.Type) { case ResponseImageType.Bmp: await image.SaveAsBmpAsync(ms); break; case ResponseImageType.Gif: await image.SaveAsGifAsync(ms); break; case ResponseImageType.Jpeg: await image.SaveAsJpegAsync(ms, new JpegEncoder { Quality = stubImage.JpegQuality }); break; default: await image.SaveAsPngAsync(ms); break; } bytes = ms.ToArray(); _fileService.WriteAllBytes(cacheFilePath, bytes); } response.Body = bytes; return(StubResponseWriterResultModel.IsExecuted(GetType().Name)); }