diff --git a/pkgs/http_profile/README.md b/pkgs/http_profile/README.md index 1ca1305b76..3b6511fe42 100644 --- a/pkgs/http_profile/README.md +++ b/pkgs/http_profile/README.md @@ -1,2 +1,71 @@ -An **experimental** package that allows HTTP clients outside of the Dart SDK -to integrate with the DevTools Network tab. +[![pub package](https://img.shields.io/pub/v/http_profile.svg)](https://pub.dev/packages/http_profile) +[![package publisher](https://img.shields.io/pub/publisher/http_profile.svg)](https://pub.dev/packages/http_profile/publisher) + +A package that allows HTTP clients outside of the Dart SDK to integrate with +the DevTools Network View. + +**NOTE:** This package is meant for developers *implementing* HTTP clients, not +developers *using* HTTP clients. + +## Using + +`HttpClientRequestProfile.profile` returns an `HttpClientRequestProfile` object +if HTTP profiling is enabled. Populating the fields of that object with +information about an HTTP request and about the response to that request will +make that information show up in the +[DevTools Network View](https://docs.flutter.dev/tools/devtools/network). + +```dart +import 'package:http_profile/http_profile.dart'; + +Future get(Uri uri) { + final profile = HttpClientRequestProfile.profile( + requestStartTime: DateTime.now(), + requestMethod: 'GET', + requestUri: uri.toString(), + ); + profile?.connectionInfo = { + 'localPort': 1285, + 'remotePort': 443, + 'connectionPoolId': '21x23', + }; + + profile.requestData.proxyDetails = HttpProfileProxyData( + host: 'https://www.example.com', + username: 'abc123', + isDirect: true, + port: 4321, + ); + + // Make the HTTP request and populate the response data. + + profile.responseData.headersListValues = { + 'connection': ['keep-alive'], + 'cache-control': ['max-age=43200'], + 'content-type': ['application/json', 'charset=utf-8'], + }; + + return responseString; +} +``` + +Refer to the source of +[`package:cupertino_http`](https://github.com/dart-lang/http/blob/master/pkgs/cupertino_http/lib/src/cupertino_client.dart) +to see a comprehensive example of how `package:http_profile` can be integrated +into an HTTP client. + +## Status: experimental + +**NOTE**: This package is currently experimental and published under the +[labs.dart.dev](https://dart.dev/dart-team-packages) pub publisher in order to +solicit feedback. + +For packages in the labs.dart.dev publisher we generally plan to either graduate +the package into a supported publisher (dart.dev, tools.dart.dev) after a period +of feedback and iteration, or discontinue the package. These packages have a +much higher expected rate of API and breaking changes. + +Your feedback is valuable and will help us evolve this package. For general +feedback, suggestions, and comments, please file an issue in the +[bug tracker](https://github.com/dart-lang/http/issues). + diff --git a/pkgs/http_profile/lib/src/http_client_request_profile.dart b/pkgs/http_profile/lib/src/http_client_request_profile.dart index 9b7b2157e3..c928735d44 100644 --- a/pkgs/http_profile/lib/src/http_client_request_profile.dart +++ b/pkgs/http_profile/lib/src/http_client_request_profile.dart @@ -147,12 +147,13 @@ final class HttpClientRequestProfile { responseData = HttpProfileResponseData._(_data, _updated); _data['requestBodyBytes'] = []; requestData._body.stream.listen( - (final bytes) => (_data['requestBodyBytes'] as List).addAll(bytes), - ); + (final bytes) => (_data['requestBodyBytes'] as List).addAll(bytes), + onError: (e) {}); _data['responseBodyBytes'] = []; responseData._body.stream.listen( - (final bytes) => (_data['responseBodyBytes'] as List).addAll(bytes), - ); + (final bytes) => + (_data['responseBodyBytes'] as List).addAll(bytes), + onError: (e) {}); // This entry is needed to support the updatedSince parameter of // ext.dart.io.getHttpProfile. _updated(); diff --git a/pkgs/http_profile/lib/src/http_profile_request_data.dart b/pkgs/http_profile/lib/src/http_profile_request_data.dart index 537643cc2c..60b1d8e8fe 100644 --- a/pkgs/http_profile/lib/src/http_profile_request_data.dart +++ b/pkgs/http_profile/lib/src/http_profile_request_data.dart @@ -55,6 +55,9 @@ final class HttpProfileRequestData { _data['requestData'] as Map; /// A sink that can be used to record the body of the request. + /// + /// Errors added to [bodySink] (for example with [StreamSink.addError]) are + /// ignored. StreamSink> get bodySink => _body.sink; /// The body of the request represented as an unmodifiable list of bytes. diff --git a/pkgs/http_profile/lib/src/http_profile_response_data.dart b/pkgs/http_profile/lib/src/http_profile_response_data.dart index 8cf0f682d6..920b97d601 100644 --- a/pkgs/http_profile/lib/src/http_profile_response_data.dart +++ b/pkgs/http_profile/lib/src/http_profile_response_data.dart @@ -62,6 +62,9 @@ final class HttpProfileResponseData { .map(HttpProfileRedirectData._fromJson)); /// A sink that can be used to record the body of the response. + /// + /// Errors added to [bodySink] (for example with [StreamSink.addError]) are + /// ignored. StreamSink> get bodySink => _body.sink; /// The body of the response represented as an unmodifiable list of bytes. diff --git a/pkgs/http_profile/test/http_profile_request_data_test.dart b/pkgs/http_profile/test/http_profile_request_data_test.dart index 36c79a766f..500cd95f52 100644 --- a/pkgs/http_profile/test/http_profile_request_data_test.dart +++ b/pkgs/http_profile/test/http_profile_request_data_test.dart @@ -348,9 +348,11 @@ void main() { expect(profile.requestData.bodyBytes, isEmpty); profile.requestData.bodySink.add([1, 2, 3]); + profile.requestData.bodySink.addError('this is an error'); + profile.requestData.bodySink.add([4, 5]); await profile.requestData.close(); - expect(requestBodyBytes, [1, 2, 3]); - expect(profile.requestData.bodyBytes, [1, 2, 3]); + expect(requestBodyBytes, [1, 2, 3, 4, 5]); + expect(profile.requestData.bodyBytes, [1, 2, 3, 4, 5]); }); } diff --git a/pkgs/http_profile/test/http_profile_response_data_test.dart b/pkgs/http_profile/test/http_profile_response_data_test.dart index 9b73cb7b38..a9bc9a827c 100644 --- a/pkgs/http_profile/test/http_profile_response_data_test.dart +++ b/pkgs/http_profile/test/http_profile_response_data_test.dart @@ -392,9 +392,11 @@ void main() { expect(profile.responseData.bodyBytes, isEmpty); profile.responseData.bodySink.add([1, 2, 3]); + profile.responseData.bodySink.addError('this is an error'); + profile.responseData.bodySink.add([4, 5]); await profile.responseData.close(); - expect(responseBodyBytes, [1, 2, 3]); - expect(profile.responseData.bodyBytes, [1, 2, 3]); + expect(responseBodyBytes, [1, 2, 3, 4, 5]); + expect(profile.responseData.bodyBytes, [1, 2, 3, 4, 5]); }); }