From 40c2ee99e7091bdb2a098d20f55469fa59b14288 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Wed, 25 May 2022 20:21:25 +0000 Subject: [PATCH] Add Response.url Closes #321, closes #623, closes #692 Fixes #293 Add a Uri field to BaseResponse with the final, potentially redirected, url for the content. The field is nullable for backwards compatibility - TODO: consider if this should be non-nullable from the start, or if it can be published nullable first and become non-nullable (and the constructor arg required) in the next breaking release. This may break tests which use bocks but do not mock the field used to read the URL. --- lib/src/base_request.dart | 1 + lib/src/base_response.dart | 3 +++ lib/src/browser_client.dart | 5 +++++ lib/src/io_client.dart | 3 +++ lib/src/io_streamed_response.dart | 2 ++ lib/src/mock_client.dart | 2 ++ lib/src/response.dart | 4 ++++ lib/src/streamed_response.dart | 2 ++ test/io/request_test.dart | 2 ++ 9 files changed, 24 insertions(+) diff --git a/lib/src/base_request.dart b/lib/src/base_request.dart index fd18bad332..bf0457633f 100644 --- a/lib/src/base_request.dart +++ b/lib/src/base_request.dart @@ -137,6 +137,7 @@ abstract class BaseRequest { request: response.request, headers: response.headers, isRedirect: response.isRedirect, + url: response.url, persistentConnection: response.persistentConnection, reasonPhrase: response.reasonPhrase); } catch (_) { diff --git a/lib/src/base_response.dart b/lib/src/base_response.dart index a09dcea4ed..131df1ff31 100644 --- a/lib/src/base_response.dart +++ b/lib/src/base_response.dart @@ -31,6 +31,8 @@ abstract class BaseResponse { final bool isRedirect; + final Uri? url; + /// Whether the server requested that a persistent connection be maintained. final bool persistentConnection; @@ -39,6 +41,7 @@ abstract class BaseResponse { this.request, this.headers = const {}, this.isRedirect = false, + this.url, this.persistentConnection = true, this.reasonPhrase}) { if (statusCode < 100) { diff --git a/lib/src/browser_client.dart b/lib/src/browser_client.dart index b046b01993..fc1720529b 100644 --- a/lib/src/browser_client.dart +++ b/lib/src/browser_client.dart @@ -53,10 +53,15 @@ class BrowserClient extends BaseClient { unawaited(xhr.onLoad.first.then((_) { var body = (xhr.response as ByteBuffer).asUint8List(); + var responseUrl = xhr.responseUrl; + var url = (responseUrl != null && responseUrl.isNotEmpty) + ? Uri.parse(responseUrl) + : null; completer.complete(StreamedResponse( ByteStream.fromBytes(body), xhr.status!, contentLength: body.length, request: request, + url: url, headers: xhr.responseHeaders, reasonPhrase: xhr.statusText)); })); diff --git a/lib/src/io_client.dart b/lib/src/io_client.dart index b26ec0486b..7e489b598e 100644 --- a/lib/src/io_client.dart +++ b/lib/src/io_client.dart @@ -59,6 +59,9 @@ class IOClient extends BaseClient { request: request, headers: headers, isRedirect: response.isRedirect, + url: response.redirects.isNotEmpty + ? response.redirects.last.location + : request.url, persistentConnection: response.persistentConnection, reasonPhrase: response.reasonPhrase, inner: response); diff --git a/lib/src/io_streamed_response.dart b/lib/src/io_streamed_response.dart index 21744858b3..0948f894f1 100644 --- a/lib/src/io_streamed_response.dart +++ b/lib/src/io_streamed_response.dart @@ -22,6 +22,7 @@ class IOStreamedResponse extends StreamedResponse { BaseRequest? request, Map headers = const {}, bool isRedirect = false, + Uri? url, bool persistentConnection = true, String? reasonPhrase, HttpClientResponse? inner}) @@ -31,6 +32,7 @@ class IOStreamedResponse extends StreamedResponse { request: request, headers: headers, isRedirect: isRedirect, + url: url, persistentConnection: persistentConnection, reasonPhrase: reasonPhrase); diff --git a/lib/src/mock_client.dart b/lib/src/mock_client.dart index bf2df40ee7..cc46d30989 100644 --- a/lib/src/mock_client.dart +++ b/lib/src/mock_client.dart @@ -46,6 +46,7 @@ class MockClient extends BaseClient { request: response.request, headers: response.headers, isRedirect: response.isRedirect, + url: response.url, persistentConnection: response.persistentConnection, reasonPhrase: response.reasonPhrase); }); @@ -60,6 +61,7 @@ class MockClient extends BaseClient { request: response.request, headers: response.headers, isRedirect: response.isRedirect, + url: response.url, persistentConnection: response.persistentConnection, reasonPhrase: response.reasonPhrase); }); diff --git a/lib/src/response.dart b/lib/src/response.dart index 01899887a7..1ddd4891e8 100644 --- a/lib/src/response.dart +++ b/lib/src/response.dart @@ -32,12 +32,14 @@ class Response extends BaseResponse { {BaseRequest? request, Map headers = const {}, bool isRedirect = false, + Uri? url, bool persistentConnection = true, String? reasonPhrase}) : this.bytes(_encodingForHeaders(headers).encode(body), statusCode, request: request, headers: headers, isRedirect: isRedirect, + url: url, persistentConnection: persistentConnection, reasonPhrase: reasonPhrase); @@ -46,6 +48,7 @@ class Response extends BaseResponse { {BaseRequest? request, Map headers = const {}, bool isRedirect = false, + Uri? url, bool persistentConnection = true, String? reasonPhrase}) : bodyBytes = toUint8List(bodyBytes), @@ -54,6 +57,7 @@ class Response extends BaseResponse { request: request, headers: headers, isRedirect: isRedirect, + url: url, persistentConnection: persistentConnection, reasonPhrase: reasonPhrase); diff --git a/lib/src/streamed_response.dart b/lib/src/streamed_response.dart index e082dced0e..bf17385b03 100644 --- a/lib/src/streamed_response.dart +++ b/lib/src/streamed_response.dart @@ -23,6 +23,7 @@ class StreamedResponse extends BaseResponse { BaseRequest? request, Map headers = const {}, bool isRedirect = false, + Uri? url, bool persistentConnection = true, String? reasonPhrase}) : stream = toByteStream(stream), @@ -31,6 +32,7 @@ class StreamedResponse extends BaseResponse { request: request, headers: headers, isRedirect: isRedirect, + url: url, persistentConnection: persistentConnection, reasonPhrase: reasonPhrase); } diff --git a/test/io/request_test.dart b/test/io/request_test.dart index 97555f9782..7505304bc9 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, serverUrl.resolve('/redirect')); }); test('with redirects', () async { @@ -53,6 +54,7 @@ void main() { expect(response.statusCode, equals(200)); final bytesString = await response.stream.bytesToString(); expect(bytesString, parse(containsPair('path', '/'))); + expect(response.url, serverUrl.resolve('/')); }); test('exceeding max redirects', () async {