Skip to content

Commit eb9e3d1

Browse files
Fix ResponseUri returning original URL instead of redirect target when FollowRedirects=false (#2346) (#2350)
When FollowRedirects is disabled and the server returns a 3xx redirect, ResponseUri now returns the Location header value (the redirect target) instead of the original request URL. Non-redirect responses are unaffected. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 5c5a6b1 commit eb9e3d1

2 files changed

Lines changed: 33 additions & 1 deletion

File tree

src/RestSharp/Response/RestResponse.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ async Task<RestResponse> GetDefaultResponse() {
6868
IsSuccessStatusCode = httpResponse.IsSuccessStatusCode,
6969
RawBytes = bytes,
7070
ResponseStatus = options.CalculateResponseStatus(httpResponse),
71-
ResponseUri = httpResponse.RequestMessage?.RequestUri,
71+
ResponseUri = GetResponseUri(httpResponse),
7272
RootElement = request.RootElement,
7373
Server = httpResponse.Headers.Server.ToString(),
7474
StatusCode = httpResponse.StatusCode,
@@ -79,6 +79,19 @@ async Task<RestResponse> GetDefaultResponse() {
7979
}
8080

8181
public RestResponse() : this(new()) { }
82+
83+
static Uri? GetResponseUri(HttpResponseMessage httpResponse) {
84+
var requestUri = httpResponse.RequestMessage?.RequestUri;
85+
86+
if ((int)httpResponse.StatusCode is >= 300 and < 400
87+
&& httpResponse.Headers.Location is { } location) {
88+
return location.IsAbsoluteUri || requestUri == null
89+
? location
90+
: new Uri(requestUri, location);
91+
}
92+
93+
return requestUri;
94+
}
8295
}
8396

8497
public delegate ResponseStatus CalculateResponseStatus(HttpResponseMessage httpResponse);

test/RestSharp.Tests.Integrated/RedirectTests.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,24 @@ public async Task Can_Perform_GET_Async_With_Redirect() {
1414
response.Data!.Message.Should().Be(val);
1515
}
1616

17+
[Fact]
18+
public async Task ResponseUri_Should_Be_Final_Url_When_FollowRedirects_True() {
19+
var request = new RestRequest("redirect");
20+
var response = await _client.ExecuteAsync(request);
21+
22+
response.ResponseUri.Should().Be(new Uri(new Uri(server.Url!), "success"));
23+
}
24+
25+
[Fact]
26+
public async Task ResponseUri_Should_Be_Redirect_Target_When_FollowRedirects_False() {
27+
using var client = new RestClient(new RestClientOptions(server.Url!) { FollowRedirects = false });
28+
29+
var request = new RestRequest("redirect");
30+
var response = await client.ExecuteAsync(request);
31+
32+
response.StatusCode.Should().Be(HttpStatusCode.Redirect);
33+
response.ResponseUri.Should().Be(new Uri(new Uri(server.Url!), "success"));
34+
}
35+
1736
public void Dispose() => _client.Dispose();
1837
}

0 commit comments

Comments
 (0)