diff --git a/lib/src/base_request.dart b/lib/src/base_request.dart index fd18bad332..7f73c58d49 100644 --- a/lib/src/base_request.dart +++ b/lib/src/base_request.dart @@ -136,6 +136,7 @@ abstract class BaseRequest { contentLength: response.contentLength, request: response.request, headers: response.headers, + url: response.url, isRedirect: response.isRedirect, persistentConnection: response.persistentConnection, reasonPhrase: response.reasonPhrase); diff --git a/lib/src/base_response.dart b/lib/src/base_response.dart index a09dcea4ed..aefe33cae2 100644 --- a/lib/src/base_response.dart +++ b/lib/src/base_response.dart @@ -29,6 +29,9 @@ abstract class BaseResponse { // TODO(nweiz): make this a HttpHeaders object. final Map headers; + /// The url of the final response(possibly after redirections). + final String? url; + final bool isRedirect; /// Whether the server requested that a persistent connection be maintained. @@ -38,6 +41,7 @@ abstract class BaseResponse { {this.contentLength, this.request, this.headers = const {}, + this.url, this.isRedirect = false, this.persistentConnection = true, this.reasonPhrase}) { diff --git a/lib/src/io_client.dart b/lib/src/io_client.dart index b26ec0486b..cd047177cd 100644 --- a/lib/src/io_client.dart +++ b/lib/src/io_client.dart @@ -58,6 +58,9 @@ class IOClient extends BaseClient { response.contentLength == -1 ? null : response.contentLength, request: request, headers: headers, + url: response.redirects.isEmpty + ? request.url.toString() + : response.redirects.last.location.toString(), isRedirect: response.isRedirect, persistentConnection: response.persistentConnection, reasonPhrase: response.reasonPhrase, diff --git a/lib/src/io_streamed_response.dart b/lib/src/io_streamed_response.dart index 21744858b3..e557befd9f 100644 --- a/lib/src/io_streamed_response.dart +++ b/lib/src/io_streamed_response.dart @@ -21,6 +21,7 @@ class IOStreamedResponse extends StreamedResponse { {int? contentLength, BaseRequest? request, Map headers = const {}, + String? url, bool isRedirect = false, bool persistentConnection = true, String? reasonPhrase, @@ -30,6 +31,7 @@ class IOStreamedResponse extends StreamedResponse { contentLength: contentLength, request: request, headers: headers, + url: url, isRedirect: isRedirect, persistentConnection: persistentConnection, reasonPhrase: reasonPhrase); diff --git a/lib/src/response.dart b/lib/src/response.dart index 01899887a7..8713d27223 100644 --- a/lib/src/response.dart +++ b/lib/src/response.dart @@ -31,12 +31,14 @@ class Response extends BaseResponse { Response(String body, int statusCode, {BaseRequest? request, Map headers = const {}, + String? url, bool isRedirect = false, bool persistentConnection = true, String? reasonPhrase}) : this.bytes(_encodingForHeaders(headers).encode(body), statusCode, request: request, headers: headers, + url: url, isRedirect: isRedirect, persistentConnection: persistentConnection, reasonPhrase: reasonPhrase); @@ -45,6 +47,7 @@ class Response extends BaseResponse { Response.bytes(List bodyBytes, int statusCode, {BaseRequest? request, Map headers = const {}, + String? url, bool isRedirect = false, bool persistentConnection = true, String? reasonPhrase}) @@ -53,6 +56,7 @@ class Response extends BaseResponse { contentLength: bodyBytes.length, request: request, headers: headers, + url: url, isRedirect: isRedirect, persistentConnection: persistentConnection, reasonPhrase: reasonPhrase); @@ -64,6 +68,7 @@ class Response extends BaseResponse { return Response.bytes(body, response.statusCode, request: response.request, headers: response.headers, + url: response.url, isRedirect: response.isRedirect, persistentConnection: response.persistentConnection, reasonPhrase: response.reasonPhrase); diff --git a/lib/src/streamed_response.dart b/lib/src/streamed_response.dart index e082dced0e..56e037745d 100644 --- a/lib/src/streamed_response.dart +++ b/lib/src/streamed_response.dart @@ -22,6 +22,7 @@ class StreamedResponse extends BaseResponse { {int? contentLength, BaseRequest? request, Map headers = const {}, + String? url, bool isRedirect = false, bool persistentConnection = true, String? reasonPhrase}) @@ -30,6 +31,7 @@ class StreamedResponse extends BaseResponse { contentLength: contentLength, request: request, headers: headers, + url: url, isRedirect: isRedirect, persistentConnection: persistentConnection, reasonPhrase: reasonPhrase); diff --git a/test/io/request_test.dart b/test/io/request_test.dart index 97555f9782..fe93fbe284 100644 --- a/test/io/request_test.dart +++ b/test/io/request_test.dart @@ -44,6 +44,7 @@ void main() { final response = await request.send(); expect(response.statusCode, equals(302)); + expect(response.url, equals(serverUrl.resolve('/redirect').toString())); }); test('with redirects', () async { @@ -51,6 +52,7 @@ void main() { final response = await request.send(); expect(response.statusCode, equals(200)); + expect(response.url, equals(serverUrl.resolve('/').toString())); final bytesString = await response.stream.bytesToString(); expect(bytesString, parse(containsPair('path', '/'))); }); diff --git a/test/response_test.dart b/test/response_test.dart index 38061c1ef4..da1c994d1b 100644 --- a/test/response_test.dart +++ b/test/response_test.dart @@ -69,5 +69,15 @@ void main() { var response = await http.Response.fromStream(streamResponse); expect(response.bodyBytes, equals([104, 101, 108, 108, 111])); }); + + test('sets url', () async { + var controller = StreamController>(sync: true); + var streamResponse = http.StreamedResponse(controller.stream, 302, + contentLength: 5, url: 'https://example.com'); + controller.add([104, 101, 108, 108, 111]); + unawaited(controller.close()); + var response = await http.Response.fromStream(streamResponse); + expect(response.url, equals('https://example.com')); + }); }); }