Advertisement
Guest User

Untitled

a guest
Jun 24th, 2019
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.38 KB | None | 0 0
  1. public class RequestResponseLoggingMiddleware
  2. {
  3. private readonly RequestDelegate _next;
  4. private readonly ILogger<RequestResponseLoggingMiddleware> _logger;
  5. private readonly RecyclableMemoryStreamManager _recyclableMemoryStreamManager;
  6. private const int ReadChunkBufferLength = 4096;
  7.  
  8. public RequestResponseLoggingMiddleware(RequestDelegate next, ILogger<RequestResponseLoggingMiddleware> logger)
  9. {
  10. _next = next;
  11. _logger = logger;
  12. _recyclableMemoryStreamManager = new RecyclableMemoryStreamManager();
  13. }
  14.  
  15. public async Task Invoke(HttpContext context)
  16. {
  17. var requestProfilerModel = new RequestProfilerModel
  18. {
  19. RequestTime = new DateTimeOffset(),
  20. Context = context,
  21. Request = await FormatRequestAsync(context)
  22. };
  23.  
  24. var originalBody = context.Response.Body;
  25.  
  26. using (var newResponseBody = _recyclableMemoryStreamManager.GetStream())
  27. {
  28. context.Response.Body = newResponseBody;
  29.  
  30. await _next(context);
  31.  
  32. newResponseBody.Seek(0, SeekOrigin.Begin);
  33. await newResponseBody.CopyToAsync(originalBody);
  34.  
  35. newResponseBody.Seek(0, SeekOrigin.Begin);
  36. requestProfilerModel.Response = await FormatResponseAsync(context, newResponseBody);
  37. requestProfilerModel.ResponseTime = new DateTimeOffset();
  38.  
  39. _logger.LogInformation(requestProfilerModel.Request);
  40. _logger.LogInformation(requestProfilerModel.Response);
  41. }
  42. }
  43.  
  44. private async Task<string> FormatResponseAsync(HttpContext context, Stream newResponseBody)
  45. {
  46. var request = context.Request;
  47. var response = context.Response;
  48.  
  49. return $"Http Response Information: {Environment.NewLine}" +
  50. $"Schema: {request.Scheme} {Environment.NewLine}" +
  51. $"Host: {request.Host} {Environment.NewLine}" +
  52. $"Path: {request.Path} {Environment.NewLine}" +
  53. $"QueryString: {request.QueryString} {Environment.NewLine}" +
  54. $"Headers: {Environment.NewLine}" + FormatHeaders(response.Headers) +
  55. $"StatusCode: {response.StatusCode} {Environment.NewLine}" +
  56. $"Response Body: {await ReadStreamInChunksAsync(newResponseBody)}";
  57. }
  58.  
  59. private async Task<string> FormatRequestAsync(HttpContext context)
  60. {
  61. var request = context.Request;
  62.  
  63. return $"Http Request Information: {Environment.NewLine}" +
  64. $"Schema:{request.Scheme} {Environment.NewLine}" +
  65. $"Host: {request.Host} {Environment.NewLine}" +
  66. $"Path: {request.Path} {Environment.NewLine}" +
  67. $"QueryString: {request.QueryString} {Environment.NewLine}" +
  68. $"Headers: {Environment.NewLine}" + FormatHeaders(request.Headers) +
  69. $"Request Body: {await GetRequestBodyAsync(request)}";
  70. }
  71.  
  72. private string FormatHeaders(IHeaderDictionary headers)
  73. {
  74. var stringBuilder = new StringBuilder();
  75.  
  76. foreach (var (key, value) in headers)
  77. {
  78. stringBuilder.AppendLine($"- {key}: {value}");
  79. }
  80.  
  81. return stringBuilder.ToString();
  82. }
  83.  
  84. public async Task<string> GetRequestBodyAsync(HttpRequest request)
  85. {
  86. request.EnableBuffering();
  87. request.EnableRewind();
  88. using (var stream = _recyclableMemoryStreamManager.GetStream())
  89. {
  90. await request.Body.CopyToAsync(stream);
  91. request.Body.Seek(0, SeekOrigin.Begin);
  92. return await ReadStreamInChunksAsync(stream);
  93. }
  94. }
  95.  
  96. private static async Task<string> ReadStreamInChunksAsync(Stream stream)
  97. {
  98. stream.Seek(0, SeekOrigin.Begin);
  99. string result;
  100.  
  101. using (var stringWriter = new StringWriter())
  102. using (var streamReader = new StreamReader(stream))
  103. {
  104. var readChunk = new char[ReadChunkBufferLength];
  105. int readChunkLength;
  106. //do while: is useful for the last iteration in case readChunkLength < chunkLength
  107. do
  108. {
  109. readChunkLength = await streamReader.ReadBlockAsync(readChunk, 0, ReadChunkBufferLength);
  110. await stringWriter.WriteAsync(readChunk, 0, readChunkLength);
  111. } while (readChunkLength > 0);
  112.  
  113. result = stringWriter.ToString();
  114. }
  115.  
  116. return result;
  117. }
  118. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement