Skip to content

Commit

Permalink
feat: prevent serialization of CancellationToken? (#1917)
Browse files Browse the repository at this point in the history
Co-authored-by: Chris Pulman <[email protected]>
  • Loading branch information
TimothyMakkison and ChrisPulman authored Nov 6, 2024
1 parent c302e1c commit 3dba936
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
56 changes: 56 additions & 0 deletions Refit.Tests/RestService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,18 @@ public interface IFragmentApi
Task QueryAfterFragment();
}

public interface ICancellableApi
{
[Get("/foo")]
Task GetWithCancellation(CancellationToken token = default);

[Get("/foo")]
Task<string> GetWithCancellationAndReturn(CancellationToken token = default);

[Get("/foo")]
Task GetWithNullableCancellation(CancellationToken? token);
}

public class HttpBinGet
{
public Dictionary<string, object> Args { get; set; }
Expand Down Expand Up @@ -2547,6 +2559,50 @@ public async Task ShouldStripQueryAfterFragment()
mockHttp.VerifyNoOutstandingExpectation();
}

[Fact]
public async Task TaskShouldCancelWhenRequested()
{
var ctSource = new CancellationTokenSource();
var token = ctSource.Token;

var fixture = RestService.For<ICancellableApi>("https://github.com");

ctSource.Cancel();
var task = fixture.GetWithCancellation(token);
await Assert.ThrowsAsync<TaskCanceledException>(async () => await task);
}

[Fact]
public async Task TaskResultShouldCancelWhenRequested()
{
var ctSource = new CancellationTokenSource();
var token = ctSource.Token;

var fixture = RestService.For<ICancellableApi>("https://github.com");

ctSource.Cancel();
var task = fixture.GetWithCancellationAndReturn(token);
await Assert.ThrowsAsync<TaskCanceledException>(async () => await task);
}


[Fact]
public async Task NullableCancellationTokenShouldBeIgnored()
{
var mockHttp = new MockHttpMessageHandler();
var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, };

mockHttp
.Expect(HttpMethod.Get, "https://github.com/foo")
.Respond(HttpStatusCode.OK);

var fixture = RestService.For<ICancellableApi>("https://github.com", settings);

await fixture.GetWithNullableCancellation(null);

mockHttp.VerifyNoOutstandingExpectation();
}

[Fact]
public async Task TypeCollisionTest()
{
Expand Down
2 changes: 1 addition & 1 deletion Refit/RestMethodInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public RestMethodInfoInternal(
// Exclude cancellation token parameters from this list
ParameterInfoArray = methodInfo
.GetParameters()
.Where(static p => p.ParameterType != typeof(CancellationToken))
.Where(static p => p.ParameterType != typeof(CancellationToken) && p.ParameterType != typeof(CancellationToken?))
.ToArray();
(ParameterMap, FragmentPath) = BuildParameterMap(RelativePath, ParameterInfoArray);
BodyParameterInfo = FindBodyParameter(ParameterInfoArray, IsMultipart, hma.Method);
Expand Down

0 comments on commit 3dba936

Please sign in to comment.