public async Task RequestDepthExcluded_ExistingRequestWithoutDepth_HeaderWithRequestId() { var existingRequestId = new RequestIdBuilder() .WithNoDepth() .Build(); var options = new RequestChainOptions { IncludeRequestDepth = false }; Guid requestIdGuid; using (var server = new RequestIdTestServer(options)) using (var client = server.CreateClient()) { client.ApplyRequestChain(existingRequestId); var result = await client.MakeRequestAndGetRequestHeader(); result.Should() .NotBeNullOrWhiteSpace(); result.Should() .NotContain(":", "the header only contains the request, not the depth"); Guid.TryParse(result, out requestIdGuid) .Should() .BeTrue(); } }
public async Task RequestDepth_FromCustomRequestHeader_RequestId() { var customRequestHeader = "custom-rc-header"; var originalDepth = 4; var expectedDepth = 5; var existingRequestId = new RequestIdBuilder() .WithDepth(originalDepth) .WithHeader(customRequestHeader) .Build(); var options = new RequestChainOptions { RequestIdHeaderKey = customRequestHeader }; using (var server = new RequestIdTestServer(options)) using (var client = server.CreateClient()) { client.ApplyRequestChain(existingRequestId); var result = await client.MakeRequestAndGetRequestDepth(); result.Should() .Be(expectedDepth, "the original depth should increment when ApplyRequestChain is called on client"); } }
public async Task RequestId_FromCustomRequestHeader_RequestId() { var customRequestHeader = "custom-rc-header"; var expectedId = Guid.NewGuid(); var existingRequestId = new RequestIdBuilder() .WithRequetId(expectedId) .WithHeader(customRequestHeader) .Build(); var options = new RequestChainOptions { RequestIdHeaderKey = customRequestHeader }; using (var server = new RequestIdTestServer(options)) using (var client = server.CreateClient()) { client.ApplyRequestChain(existingRequestId); var result = await client.MakeRequestAndGetRequestId(); result.Should() .Be(expectedId, "the requestId comes from the existing request"); } }
private int?GetRequestDepth(string requestIdString, RequestChainOptions options, IHeaderDictionary headers) { if (!options.IncludeRequestDepth) { requestIdString = RemoveDepthFromHeaderIfExists(requestIdString, options, headers); return(null); } var requestDepthStr = requestIdString .Split(SplitCharacter) .Skip(1) .FirstOrDefault(); int requestDepth; if (string.IsNullOrEmpty(requestDepthStr) || !int.TryParse(requestDepthStr, out requestDepth) || requestDepth <= 0) { var msg = $"Request Depth for known RequestId {_requestId} was not found or malformed"; if (options.ThrowOnMalformedRequestHeaders) { throw new InvalidOperationException(msg); } else { _logger?.Log(options.RequestIdHeaderMalformedLogLevel, msg); return(null); } } return(requestDepth); }
public RequestIdTestServer(RequestChainOptions options = null) { var webHostBuilder = new WebHostBuilder() .ConfigureServices(services => ConfigureServices(services, options)) .Configure(ConfigureApplication); _server = new TestServer(webHostBuilder); }
internal RequestId(RequestChainOptions options) { if (options == default(RequestChainOptions)) { throw new ArgumentNullException(nameof(options)); } _options = options; }
private string RemoveDepthFromHeaderIfExists(string requestIdString, RequestChainOptions options, IHeaderDictionary headers) { requestIdString = requestIdString .Split(SplitCharacter) .First(); headers[options.RequestIdHeaderKey] = requestIdString; return(requestIdString); }
private void ConfigureServices(IServiceCollection services, RequestChainOptions options) { if (options == null) { options = new RequestChainOptions { IncludeRequestDepth = true }; } services.AddRequestChain(options); }
public async Task RequestDepthExcluded_OriginalRequest_ValidRequestId() { var options = new RequestChainOptions { IncludeRequestDepth = false }; using (var server = new RequestIdTestServer(options)) using (var client = server.CreateClient()) { var result = await client.MakeRequestAndGetRequestId(); result.Should() .NotBe(default(Guid), "it should be created by the server"); } }
public async Task RequestDepthExcluded_OriginalRequest_DepthNull() { var options = new RequestChainOptions { IncludeRequestDepth = false }; using (var server = new RequestIdTestServer(options)) using (var client = server.CreateClient()) { var result = await client.MakeRequestAndGetRequestDepth(); result.Should() .Be(null, "the request depth is disabled in options"); } }
private void CreateNewRequestId(HttpRequest request, RequestChainOptions options) { // Sets value in object _requestId = Guid.NewGuid(); string requestHeaderValue; if (options.IncludeRequestDepth) { _requestDepth = 0; requestHeaderValue = $"{_requestId}:0"; } else { _requestDepth = null; requestHeaderValue = _requestId.ToString(); } // Add it to the request header which is important if request sent through reverse proxy request.Headers.Add(options.RequestIdHeaderKey, requestHeaderValue); }
/// <summary> /// Sets the Request Id by either pulling it out of the header or creating a new one. /// </summary> /// <param name="request">Current request</param> /// <param name="options">RequestChainOptions</param> /// <returns>True if the value previously existing, false if it was newly assigned</returns> internal bool SetRequestId(HttpRequest request, RequestChainOptions options) { KeyValuePair <string, StringValues> existingRequestIdHeader = request.Headers .FirstOrDefault(a => string.Equals(a.Key, options.RequestIdHeaderKey, StringComparison.OrdinalIgnoreCase)); if (Equals(existingRequestIdHeader, default(KeyValuePair <string, StringValues>))) { // No request id set... creating a new one. CreateNewRequestId(request, options); _logger?.Log(options.RequestIdCreatedLogLevel, "RequestId created: {0}", _requestId); return(false); } string requestIdStr = existingRequestIdHeader.Value.FirstOrDefault(); if (!Guid.TryParse(requestIdStr.Split(SplitCharacter)[0], out _requestId)) { if (options.ThrowOnMalformedRequestHeaders) { throw new InvalidOperationException($"RequestId in header was not in correct format: \"{requestIdStr}\""); } else { CreateNewRequestId(request, options); _logger?.Log(options.RequestIdHeaderMalformedLogLevel, "RequestId in header was not in correct format \"{0}\". Replacing with new RequestId: {1}", requestIdStr, _requestId); return(false); } } else { _requestDepth = GetRequestDepth(requestIdStr, options, request.Headers); } return(true); }
public async Task RequestDepthExcluded_ExistingRequestWithoutDepth_DepthNull() { var existingRequestId = new RequestIdBuilder() .WithNoDepth() .Build(); var options = new RequestChainOptions { IncludeRequestDepth = false }; using (var server = new RequestIdTestServer(options)) using (var client = server.CreateClient()) { client.ApplyRequestChain(existingRequestId); var result = await client.MakeRequestAndGetRequestDepth(); result.Should() .Be(null, "the request depth is disabled in options"); } }