Skip to content

Commit 3dba936

Browse files
feat: prevent serialization of CancellationToken? (#1917)
Co-authored-by: Chris Pulman <[email protected]>
1 parent c302e1c commit 3dba936

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

Refit.Tests/RestService.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,18 @@ public interface IFragmentApi
321321
Task QueryAfterFragment();
322322
}
323323

324+
public interface ICancellableApi
325+
{
326+
[Get("/foo")]
327+
Task GetWithCancellation(CancellationToken token = default);
328+
329+
[Get("/foo")]
330+
Task<string> GetWithCancellationAndReturn(CancellationToken token = default);
331+
332+
[Get("/foo")]
333+
Task GetWithNullableCancellation(CancellationToken? token);
334+
}
335+
324336
public class HttpBinGet
325337
{
326338
public Dictionary<string, object> Args { get; set; }
@@ -2547,6 +2559,50 @@ public async Task ShouldStripQueryAfterFragment()
25472559
mockHttp.VerifyNoOutstandingExpectation();
25482560
}
25492561

2562+
[Fact]
2563+
public async Task TaskShouldCancelWhenRequested()
2564+
{
2565+
var ctSource = new CancellationTokenSource();
2566+
var token = ctSource.Token;
2567+
2568+
var fixture = RestService.For<ICancellableApi>("https://github.com");
2569+
2570+
ctSource.Cancel();
2571+
var task = fixture.GetWithCancellation(token);
2572+
await Assert.ThrowsAsync<TaskCanceledException>(async () => await task);
2573+
}
2574+
2575+
[Fact]
2576+
public async Task TaskResultShouldCancelWhenRequested()
2577+
{
2578+
var ctSource = new CancellationTokenSource();
2579+
var token = ctSource.Token;
2580+
2581+
var fixture = RestService.For<ICancellableApi>("https://github.com");
2582+
2583+
ctSource.Cancel();
2584+
var task = fixture.GetWithCancellationAndReturn(token);
2585+
await Assert.ThrowsAsync<TaskCanceledException>(async () => await task);
2586+
}
2587+
2588+
2589+
[Fact]
2590+
public async Task NullableCancellationTokenShouldBeIgnored()
2591+
{
2592+
var mockHttp = new MockHttpMessageHandler();
2593+
var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, };
2594+
2595+
mockHttp
2596+
.Expect(HttpMethod.Get, "https://github.com/foo")
2597+
.Respond(HttpStatusCode.OK);
2598+
2599+
var fixture = RestService.For<ICancellableApi>("https://github.com", settings);
2600+
2601+
await fixture.GetWithNullableCancellation(null);
2602+
2603+
mockHttp.VerifyNoOutstandingExpectation();
2604+
}
2605+
25502606
[Fact]
25512607
public async Task TypeCollisionTest()
25522608
{

Refit/RestMethodInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public RestMethodInfoInternal(
8989
// Exclude cancellation token parameters from this list
9090
ParameterInfoArray = methodInfo
9191
.GetParameters()
92-
.Where(static p => p.ParameterType != typeof(CancellationToken))
92+
.Where(static p => p.ParameterType != typeof(CancellationToken) && p.ParameterType != typeof(CancellationToken?))
9393
.ToArray();
9494
(ParameterMap, FragmentPath) = BuildParameterMap(RelativePath, ParameterInfoArray);
9595
BodyParameterInfo = FindBodyParameter(ParameterInfoArray, IsMultipart, hma.Method);

0 commit comments

Comments
 (0)