diff --git a/src/Tgstation.Server.Client/ApiClient.cs b/src/Tgstation.Server.Client/ApiClient.cs
index e2d7aab334..7721de3138 100644
--- a/src/Tgstation.Server.Client/ApiClient.cs
+++ b/src/Tgstation.Server.Client/ApiClient.cs
@@ -1,5 +1,6 @@
using Newtonsoft.Json;
using System;
+using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
@@ -27,10 +28,15 @@ namespace Tgstation.Server.Client
}
///
- /// The for the
+ /// The for the
///
readonly HttpClient httpClient;
+ ///
+ /// The s used by the
+ ///
+ readonly List requestLoggers;
+
///
/// Construct an
///
@@ -42,6 +48,7 @@ namespace Tgstation.Server.Client
Headers = apiHeaders ?? throw new ArgumentNullException(nameof(apiHeaders));
httpClient = new HttpClient();
+ requestLoggers = new List();
}
///
@@ -67,29 +74,18 @@ namespace Tgstation.Server.Client
var fullUri = new Uri(Url, route);
- HttpContent content = null;
+ var message = new HttpRequestMessage(method, fullUri);
+
if (body != null)
- content = new StringContent(JsonConvert.SerializeObject(body));
+ message.Content = new StringContent(JsonConvert.SerializeObject(body));
- Task task;
- lock (this)
- {
- httpClient.DefaultRequestHeaders.Clear();
- Headers.SetRequestHeaders(httpClient.DefaultRequestHeaders, instanceId);
+ Headers.SetRequestHeaders(message.Headers, instanceId);
- if (method == HttpMethod.Get)
- task = httpClient.GetAsync(route);
- else if (method == HttpMethod.Put)
- task = httpClient.PutAsync(fullUri, content, cancellationToken);
- else if (method == HttpMethod.Post)
- task = httpClient.PostAsync(fullUri, content, cancellationToken);
- else if (method == HttpMethod.Delete)
- task = httpClient.DeleteAsync(fullUri, cancellationToken);
- else
- throw new NotSupportedException();
- }
+ await Task.WhenAll(requestLoggers.Select(x => x.LogRequest(message, cancellationToken))).ConfigureAwait(false);
- var response = await task.ConfigureAwait(false);
+ var response = await httpClient.SendAsync(message, cancellationToken).ConfigureAwait(false);
+
+ await Task.WhenAll(requestLoggers.Select(x => x.LogResponse(response, cancellationToken))).ConfigureAwait(false);
var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
@@ -173,5 +169,8 @@ namespace Tgstation.Server.Client
///
public Task Create(string route, long instanceId, CancellationToken cancellationToken) => RunRequest(route, new object(), HttpMethod.Put, instanceId, cancellationToken);
+
+ ///
+ public void AddRequestLogger(IRequestLogger requestLogger) => requestLoggers.Add(requestLogger ?? throw new ArgumentNullException(nameof(requestLogger)));
}
}
\ No newline at end of file
diff --git a/src/Tgstation.Server.Client/IApiClient.cs b/src/Tgstation.Server.Client/IApiClient.cs
index e2a4346396..acf5fdbf0a 100644
--- a/src/Tgstation.Server.Client/IApiClient.cs
+++ b/src/Tgstation.Server.Client/IApiClient.cs
@@ -16,6 +16,12 @@ namespace Tgstation.Server.Client
TimeSpan Timeout { get; set; }
+ ///
+ /// Adds a to the request pipeline
+ ///
+ /// The to add
+ void AddRequestLogger(IRequestLogger requestLogger);
+
Task Create(string route, TBody body, CancellationToken cancellationToken);
Task Create(string route, CancellationToken cancellationToken);
Task Read(string route, CancellationToken cancellationToken);
diff --git a/src/Tgstation.Server.Client/IRequestLogger.cs b/src/Tgstation.Server.Client/IRequestLogger.cs
new file mode 100644
index 0000000000..6115d283ca
--- /dev/null
+++ b/src/Tgstation.Server.Client/IRequestLogger.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Tgstation.Server.Client
+{
+ ///
+ /// For logging HTTP requests and responses
+ ///
+ public interface IRequestLogger
+ {
+ ///
+ /// Log a request
+ ///
+ /// The representing the request
+ /// The for the operation
+ /// A representing the running operation
+ Task LogRequest(HttpRequestMessage requestMessage, CancellationToken cancellationToken);
+
+ ///
+ /// Log a response
+ ///
+ /// The representing the request
+ /// The for the operation
+ /// A representing the running operation
+ Task LogResponse(HttpResponseMessage responseMessage, CancellationToken cancellationToken);
+ }
+}
\ No newline at end of file
diff --git a/src/Tgstation.Server.Client/IServerClient.cs b/src/Tgstation.Server.Client/IServerClient.cs
index 3fa1d13666..3bd57d287e 100644
--- a/src/Tgstation.Server.Client/IServerClient.cs
+++ b/src/Tgstation.Server.Client/IServerClient.cs
@@ -39,5 +39,11 @@ namespace Tgstation.Server.Client
/// The of the
///
Task Version(CancellationToken cancellationToken);
+
+ ///
+ /// Adds a to the request pipeline
+ ///
+ /// The to add
+ void AddRequestLogger(IRequestLogger requestLogger);
}
}
diff --git a/src/Tgstation.Server.Client/ServerClient.cs b/src/Tgstation.Server.Client/ServerClient.cs
index a592c3630d..7e34062840 100644
--- a/src/Tgstation.Server.Client/ServerClient.cs
+++ b/src/Tgstation.Server.Client/ServerClient.cs
@@ -53,7 +53,11 @@ namespace Tgstation.Server.Client
///
public void Dispose() => apiClient.Dispose();
+
///
public Task Version(CancellationToken cancellationToken) => apiClient.Read(Routes.Root, cancellationToken);
+
+ ///
+ public void AddRequestLogger(IRequestLogger requestLogger) => apiClient.AddRequestLogger(requestLogger);
}
}
\ No newline at end of file