@@ -59,7 +59,7 @@ public sealed class SeqApiClient : IDisposable
5959 /// <param name="serverUrl">The base URL of the Seq server.</param>
6060 /// <param name="apiKey">An API key to use when making requests to the server, if required.</param>
6161 /// <param name="useDefaultCredentials">Whether default credentials will be sent with HTTP requests; the default is <c>true</c>.</param>
62- [ Obsolete ( "Prefer `SeqApiClient(serverUrl, apiKey, handler => handler.UseDefaultCredentials = true )` instead." ) , EditorBrowsable ( EditorBrowsableState . Never ) ]
62+ [ Obsolete ( "Prefer `SeqApiClient(serverUrl, apiKey, createHttpMessageHandler )` instead." ) , EditorBrowsable ( EditorBrowsableState . Never ) ]
6363 public SeqApiClient ( string serverUrl , string apiKey , bool useDefaultCredentials )
6464 : this ( serverUrl , apiKey , handler => handler . UseDefaultCredentials = useDefaultCredentials )
6565 {
@@ -72,25 +72,45 @@ public SeqApiClient(string serverUrl, string apiKey, bool useDefaultCredentials)
7272 /// <param name="apiKey">An API key to use when making requests to the server, if required.</param>
7373 /// <param name="configureHttpClientHandler">An optional callback to configure the <see cref="HttpClientHandler"/> used when making HTTP requests
7474 /// to the Seq API.</param>
75- public SeqApiClient ( string serverUrl , string apiKey = null , Action < HttpClientHandler > configureHttpClientHandler = null )
75+ [ Obsolete ( "Prefer `SeqApiClient(serverUrl, apiKey, createHttpMessageHandler)` instead." ) , EditorBrowsable ( EditorBrowsableState . Never ) ]
76+ public SeqApiClient ( string serverUrl , string apiKey , Action < HttpClientHandler > configureHttpClientHandler )
77+ : this ( serverUrl , apiKey , cookies =>
78+ {
79+ var handler = new HttpClientHandler { CookieContainer = cookies } ;
80+ configureHttpClientHandler ? . Invoke ( handler ) ;
81+ return handler ;
82+ } )
83+ {
84+ }
85+
86+ /// <summary>
87+ /// Construct a <see cref="SeqApiClient"/>.
88+ /// </summary>
89+ /// <param name="serverUrl">The base URL of the Seq server.</param>
90+ /// <param name="apiKey">An API key to use when making requests to the server, if required.</param>
91+ /// <param name="createHttpMessageHandler">An optional callback to construct the HTTP message handler used when making requests
92+ /// to the Seq API. The callback receives a <see cref="CookieContainer"/> that is shared with WebSocket requests made by the client.</param>
93+ public SeqApiClient ( string serverUrl , string apiKey = null , Func < CookieContainer , HttpMessageHandler > createHttpMessageHandler = null )
7694 {
95+ // This is required for compatibility with the obsolete constructor, which we can remove sometime in 2024.
96+ var httpMessageHandler = createHttpMessageHandler ? . Invoke ( _cookies ) ??
97+ #if SOCKETS_HTTP_HANDLER
98+ new SocketsHttpHandler { CookieContainer = _cookies } ;
99+ #else
100+ new HttpClientHandler { CookieContainer = _cookies } ;
101+ #endif
102+
77103 ServerUrl = serverUrl ?? throw new ArgumentNullException ( nameof ( serverUrl ) ) ;
78104
79105 if ( ! string . IsNullOrEmpty ( apiKey ) )
80106 _apiKey = apiKey ;
81-
82- var handler = new HttpClientHandler
83- {
84- CookieContainer = _cookies
85- } ;
86-
87- configureHttpClientHandler ? . Invoke ( handler ) ;
88-
107+
89108 var baseAddress = serverUrl ;
90109 if ( ! baseAddress . EndsWith ( "/" ) )
91110 baseAddress += "/" ;
92111
93- HttpClient = new HttpClient ( handler ) { BaseAddress = new Uri ( baseAddress ) } ;
112+ HttpClient = new HttpClient ( httpMessageHandler ) ;
113+ HttpClient . BaseAddress = new Uri ( baseAddress ) ;
94114 HttpClient . DefaultRequestHeaders . Accept . Add ( new MediaTypeWithQualityHeaderValue ( SeqApiV9MediaType ) ) ;
95115
96116 if ( _apiKey != null )
@@ -251,8 +271,8 @@ public async Task PutAsync<TEntity>(ILinked entity, string link, TEntity content
251271 var linkUri = ResolveLink ( entity , link , parameters ) ;
252272 var request = new HttpRequestMessage ( HttpMethod . Put , linkUri ) { Content = MakeJsonContent ( content ) } ;
253273 var stream = await HttpSendAsync ( request , cancellationToken ) . ConfigureAwait ( false ) ;
254- using ( var reader = new StreamReader ( stream ) )
255- reader . ReadToEnd ( ) ;
274+ using var reader = new StreamReader ( stream ) ;
275+ await reader . ReadToEndAsync ( ) ;
256276 }
257277
258278 /// <summary>
@@ -270,8 +290,8 @@ public async Task DeleteAsync<TEntity>(ILinked entity, string link, TEntity cont
270290 var linkUri = ResolveLink ( entity , link , parameters ) ;
271291 var request = new HttpRequestMessage ( HttpMethod . Delete , linkUri ) { Content = MakeJsonContent ( content ) } ;
272292 var stream = await HttpSendAsync ( request , cancellationToken ) . ConfigureAwait ( false ) ;
273- using ( var reader = new StreamReader ( stream ) )
274- reader . ReadToEnd ( ) ;
293+ using var reader = new StreamReader ( stream ) ;
294+ await reader . ReadToEndAsync ( ) ;
275295 }
276296
277297 /// <summary>
@@ -345,8 +365,8 @@ async Task<string> HttpGetStringAsync(string url, CancellationToken cancellation
345365 {
346366 var request = new HttpRequestMessage ( HttpMethod . Get , url ) ;
347367 var stream = await HttpSendAsync ( request , cancellationToken ) . ConfigureAwait ( false ) ;
348- using ( var reader = new StreamReader ( stream ) )
349- return await reader . ReadToEndAsync ( ) ;
368+ using var reader = new StreamReader ( stream ) ;
369+ return await reader . ReadToEndAsync ( ) . ConfigureAwait ( false ) ;
350370 }
351371
352372 async Task < Stream > HttpSendAsync ( HttpRequestMessage request , CancellationToken cancellationToken = default )
0 commit comments