Skip to content

Commit

Permalink
Allow non-200 HTTP status codes (#419)
Browse files Browse the repository at this point in the history
* Allow non-200 HTTP status codes

* Update src/GraphQL.Client/GraphQLHttpClientOptions.cs

Co-authored-by: Alexander Rose <[email protected]>

* fix

Co-authored-by: Alexander Rose <[email protected]>
  • Loading branch information
sungam3r and rose-a authored Jul 19, 2022
1 parent 9ca13c2 commit ac2043a
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 11 deletions.
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

0 comments on commit ac2043a

Please sign in to comment.