Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions src/GraphQL.Client/GraphQLHttpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class GraphQLHttpClient : IGraphQLClient, IDisposable
private readonly Lazy<GraphQLHttpWebSocket> _lazyHttpWebSocket;
private GraphQLHttpWebSocket GraphQlHttpWebSocket => _lazyHttpWebSocket.Value;

private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
private readonly CancellationTokenSource _cancellationTokenSource = new();

private readonly bool _disposeHttpClient = false;

Expand Down Expand Up @@ -42,14 +42,17 @@ public class GraphQLHttpClient : IGraphQLClient, IDisposable

#region Constructors

public GraphQLHttpClient(string endPoint, IGraphQLWebsocketJsonSerializer serializer) : this(new Uri(endPoint), serializer) { }
public GraphQLHttpClient(string endPoint, IGraphQLWebsocketJsonSerializer serializer)
: this(new Uri(endPoint), serializer) { }

public GraphQLHttpClient(Uri endPoint, IGraphQLWebsocketJsonSerializer serializer) : this(o => o.EndPoint = endPoint, serializer) { }
public GraphQLHttpClient(Uri endPoint, IGraphQLWebsocketJsonSerializer serializer)
: this(o => o.EndPoint = endPoint, serializer) { }

public GraphQLHttpClient(Action<GraphQLHttpClientOptions> configure, IGraphQLWebsocketJsonSerializer serializer) : this(configure.New(), serializer) { }
public GraphQLHttpClient(Action<GraphQLHttpClientOptions> configure, IGraphQLWebsocketJsonSerializer serializer)
: this(configure.New(), serializer) { }

public GraphQLHttpClient(GraphQLHttpClientOptions options, IGraphQLWebsocketJsonSerializer serializer) : this(
options, serializer, new HttpClient(options.HttpMessageHandler))
public GraphQLHttpClient(GraphQLHttpClientOptions options, IGraphQLWebsocketJsonSerializer serializer)
: this(options, serializer, new HttpClient(options.HttpMessageHandler))
{
// set this flag to dispose the internally created HttpClient when GraphQLHttpClient gets disposed
_disposeHttpClient = true;
Expand Down Expand Up @@ -120,7 +123,7 @@ private async Task<GraphQLHttpResponse<TResponse>> SendHttpRequestAsync<TRespons

var contentStream = await httpResponseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false);

if (httpResponseMessage.IsSuccessStatusCode)
if (Options.IsValidResponseToDeserialize(httpResponseMessage))
{
var graphQLResponse = await JsonSerializer.DeserializeFromUtf8StreamAsync<TResponse>(contentStream, cancellationToken).ConfigureAwait(false);
return graphQLResponse.ToGraphQLHttpResponse(httpResponseMessage.Headers, httpResponseMessage.StatusCode);
Expand Down Expand Up @@ -167,7 +170,7 @@ public void Dispose()
}

private volatile bool _disposed;
private readonly object _disposeLocker = new object();
private readonly object _disposeLocker = new();

protected virtual void Dispose(bool disposing)
{
Expand Down
12 changes: 9 additions & 3 deletions src/GraphQL.Client/GraphQLHttpClientOptions.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Net;
using System.Net.Http.Headers;
using System.Net.WebSockets;

Expand All @@ -16,7 +17,7 @@ public class GraphQLHttpClientOptions
/// <summary>
/// The GraphQL EndPoint to be used for websocket connections
/// </summary>
public Uri? WebSocketEndPoint { get; set; } = null;
public Uri? WebSocketEndPoint { get; set; }

/// <summary>
/// The <see cref="System.Net.Http.HttpMessageHandler"/> that is going to be used
Expand Down Expand Up @@ -50,12 +51,17 @@ public class GraphQLHttpClientOptions
Task.FromResult(request is GraphQLHttpRequest graphQLHttpRequest ? graphQLHttpRequest : new GraphQLHttpRequest(request));

/// <summary>
/// This callback is called after successfully establishing a websocket connection but before any regular request is made.
/// Delegate to determine if GraphQL response may be properly deserialized into <see cref="GraphQLResponse{T}"/>.
/// </summary>
public Func<HttpResponseMessage, bool> IsValidResponseToDeserialize { get; set; } = r => r.IsSuccessStatusCode || r.StatusCode == HttpStatusCode.BadRequest;

/// <summary>
/// This callback is called after successfully establishing a websocket connection but before any regular request is made.
/// </summary>
public Func<GraphQLHttpClient, Task> OnWebsocketConnected { get; set; } = client => Task.CompletedTask;

/// <summary>
/// Configure additional websocket options (i.e. headers). This will not be invoked on Windows 7 when targeting .NET Framework 4.x.
/// Configure additional websocket options (i.e. headers). This will not be invoked on Windows 7 when targeting .NET Framework 4.x.
/// </summary>
public Action<ClientWebSocketOptions> ConfigureWebsocketOptions { get; set; } = options => { };

Expand Down